Skip to content

fix(atomic): make Windows/MSVC db build compile clean - #117

Merged
gburd merged 4 commits into
masterfrom
fix/msvc-atomics
Jul 31, 2026
Merged

fix(atomic): make Windows/MSVC db build compile clean#117
gburd merged 4 commits into
masterfrom
fix/msvc-atomics

Conversation

@gburd

@gburd gburd commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

Problem

The db library fails to build under MSVC (GitHub windows msbuild CI). Investigation on a Windows/ARM64 host (MSVC 17 VS2022 + MSVC 18 VS2026) surfaced four real, independent Windows-build breaks in the atomics/AIO area.

1. interlocked_val undeclared in os_atomic.c (compile, C)

The Windows Interlocked tier casts &db_atomic_t::value to LONG volatile * through the interlocked_val macro, defined only in src/mutex/mut_win32.c. In os_atomic.c it was undeclared, so (interlocked_val)(&p->value) parsed as a function call:

os_atomic.c(1957): error C2065: 'interlocked_val': undeclared identifier
os_atomic.c(1957): error C2064: term does not evaluate to a function taking 0 arguments

2. macro collisions with MSVC C++ <atomic> (compile, C++)

db.vcxproj compiles lang/cxx/*.cpp as C++. MSVC's C++ standard library transitively pulls <atomic> into every C++ TU. Two Berkeley DB macros then rewrote standard-library identifiers inside <atomic>:

  • db.h's legacy 4BSD dbm(3) alias #define store(a, b) ... clobbered std::_Atomic_storage<>::store -> C4003 / C2059.
  • dbinc/atomic.h's #define atomic_init(p, val) ... clobbered the std::atomic_init free-function template -> C2059 / C2086 redefinition of std::__os_atomic_init.

3. os_atomic.c missing from the Windows projects (link)

The atomic implementations live in os_atomic.c, which is in the Unix Makefile.in but was never added to the Windows VS project files -> LNK2019/LNK2001 unresolved external symbol __os_atomic_read/_inc/_dec/_cas/_init.

4. os_aio* missing from the Windows projects (link)

Same class of gap: the async-I/O layer (__os_aio_* in os_aio.c, referenced by mp_bh.c/mp_region.c) was added to Unix but not to Windows -> LNK2019 unresolved external symbol __os_aio_create/_submit/_reap/_destroy/_ctx_available.

Root cause

store/fetch/firstkey/nextkey/dbminit/dbmclose/delete are the historic C-only 4BSD dbm interface (delete was already #if !defined(__cplusplus)-guarded because it is a C++ keyword). atomic_init is the C11 / C++ <atomic> reserved spelling. Neither is ever called from C++ here. And os_atomic.c / os_aio*.c were added to the Unix build without updating the hand-maintained Windows project files.

Fix

  • src/os/os_atomic.c: define interlocked_val locally in the Windows tier (guarded, same self-contained pattern as mut_win32.c).
  • src/dbinc/db.in (+ regenerated build_windows/db.h via dist/s_windows): wrap the whole unprefixed 4BSD dbm macro set in #if !defined(__cplusplus), extending the existing delete precedent.
  • src/dbinc/atomic.h: define the atomic_init compatibility macro only for C.
  • build_windows/VS10/{db,db_small}.vcxproj and build_windows/VS8/{db,db_small}.vcproj: add os_atomic.c and the os_aio.c / os_aio_iocp.c / os_aio_pool.c sources (the latter two are empty TUs unless HAVE_IOCP / HAVE_AIO_THREADPOOL are configured), mirroring the Unix build.

No behavior change for C consumers; C++ TUs never used any of these macros.

Validation

  • GitHub windows msbuild CI (x64, v143): green on the final commit.
  • MSVC 17 (VS2022) and MSVC 18 (VS2026) on Windows/ARM64: os_atomic.c (/TC) and cxx_db.cpp (/TP) compile with 0 errors; a full manual compile+link of the db project sources produces libdb.dll with 0 unresolved externals (the __os_atomic_* and __os_aio_* symbols now resolve).
  • Linux autoconf default (../dist/configure && make): clean.
  • Linux --enable-cxx: clean (14 cxx objects — confirms no C++ path needs the guarded macros).
  • Meson/Ninja: clean (274/274, links libdb.so).

Depends on the regenerated Windows headers from #114 (merged); rebased onto master so this PR is only the atomics/AIO Windows-build delta.

gburd added 2 commits July 31, 2026 09:02
Two independent MSVC breaks in the Windows atomics path:

1. os_atomic.c's Windows Interlocked tier casts through interlocked_val
   (LONG volatile *) but that macro was only defined in mut_win32.c, so
   the type was undeclared in this TU -> C2065/C2064.  Define it locally
   in the same self-contained way mut_win32.c does.

2. db.h's legacy unprefixed 4BSD dbm(3) aliases (store, fetch, firstkey,
   nextkey, dbminit, dbmclose, delete) are object/function-like macros.
   In a C++ translation unit (the cxx_*.cpp files in db.vcxproj) MSVC's
   <atomic> is pulled in transitively and its std::atomic<>::store member
   collides with the 'store' macro -> C4003/C2059/C2039/C2086.  These
   names are a C-only historic interface (delete was already guarded);
   guard the whole set with #if !defined(__cplusplus).  Fixed in the
   template src/dbinc/db.in and regenerated build_windows/db.h via
   dist/s_windows.
MSVC's C++ standard library transitively includes <atomic> in every C++
translation unit (e.g. the cxx_*.cpp sources in db.vcxproj).  dbinc/atomic.h
defines a function-like macro atomic_init(p, val) whose name exactly matches
the standard std::atomic_init free function template, so the macro rewrote
that declaration and broke <atomic> (C2059/C2086 redefinition of
std::__os_atomic_init).  Berkeley DB only calls atomic_init() from C sources,
so define the macro only for C.
@github-actions

Copy link
Copy Markdown

Coccinelle convention checks

No new violations. ✅

Resolved since baseline (2) -- update dist/cocci/baseline.txt to lock these in.
rule_mutex_unbalanced|MUTEX_UNBALANCED|src/crypto/mersenne/mt19937db.c|return (ret);
rule_mutex_unbalanced|MUTEX_UNBALANCED|src/mp/mp_register.c|return (ret);

@github-actions

github-actions Bot commented Jul 31, 2026

Copy link
Copy Markdown

ABI diff vs v5.3.33 (libabigail — authoritative)

Removed exported symbols (nm -D, _NNNN version suffix normalized)

None.


Advisory: libabigail/nm is the authoritative binary-ABI check; Coccinelle is complementary source-level early warning. See dist/cocci/README.md.

gburd added 2 commits July 31, 2026 09:15
os_atomic.c holds the Windows Interlocked implementations of __os_atomic_*
but was never listed in the Windows VS project files (it is in the Unix
Makefile.in).  The db library therefore linked with unresolved externals
(__os_atomic_read/_inc/_dec/_cas, referenced by mut_win32.c, mp_*.c, lock.c,
txn.c, ...).  Add it next to os_alloc.c in the VS10 (.vcxproj) and VS8
(.vcproj) db and db_small projects.
The async-I/O layer (__os_aio_create/submit/reap/destroy/available/
ctx_available in os_aio.c, referenced by mp_bh.c and mp_region.c) was
added to the Unix Makefile.in but never to the Windows VS project files,
leaving the db library with unresolved externals at link time.  Add
os_aio.c (the generic layer + synchronous fallback, always compiled) plus
the os_aio_iocp.c and os_aio_pool.c backends (empty TUs unless HAVE_IOCP /
HAVE_AIO_THREADPOOL are configured) to the VS10 and VS8 db/db_small
projects, mirroring the Unix build.
@gburd
gburd merged commit 2c317f0 into master Jul 31, 2026
49 of 51 checks passed
@gburd
gburd deleted the fix/msvc-atomics branch July 31, 2026 13:25
gburd added a commit that referenced this pull request Jul 31, 2026
fix(atomic): make Windows/MSVC db build compile clean
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant