4444#elif defined(_WIN32)
4545
4646# include < windows.h>
47+ # include < memory>
4748
4849#else // <- Add other operating systems here
4950
@@ -107,11 +108,21 @@ static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const vo
107108
108109#elif defined(_WIN32)
109110
111+ static HMODULE win32_get_win_core_synch_api_module () {
112+ // HMODULE is documented as being a pointer type to the base address of the module in memory, which means we can
113+ // safely use std::unique_ptr here as a wrapper for the handle, with a destructor freeing the handle when this module
114+ // is unloaded.
115+ // https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types
116+ static auto module_handle = std::unique_ptr<std::remove_pointer<HMODULE>::type, decltype (&FreeLibrary)>(
117+ LoadLibraryW (L" api-ms-win-core-synch-l1-2-0.dll" ), &FreeLibrary);
118+ return module_handle.get ();
119+ }
120+
110121static void
111122__libcpp_platform_wait_on_address (__cxx_atomic_contention_t const volatile * __ptr, __cxx_contention_t __val) {
112123 // WaitOnAddress was added in Windows 8 (build 9200)
113124 static auto wait_on_address = reinterpret_cast <BOOL (WINAPI*)(volatile void *, PVOID, SIZE_T, DWORD)>(
114- GetProcAddress (GetModuleHandleW ( L" api-ms-win-core-synch-l1-2-0.dll " ), " WaitOnAddress" ));
125+ GetProcAddress (win32_get_win_core_synch_api_module ( ), " WaitOnAddress" ));
115126 if (wait_on_address != nullptr ) {
116127 wait_on_address (const_cast <__cxx_atomic_contention_t *>(__ptr), &__val, sizeof (__val), INFINITE);
117128 } else {
@@ -125,7 +136,7 @@ static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const vo
125136 if (__notify_one) {
126137 // WakeByAddressSingle was added in Windows 8 (build 9200)
127138 static auto wake_by_address_single = reinterpret_cast <void (WINAPI*)(PVOID)>(
128- GetProcAddress (GetModuleHandleW ( L" api-ms-win-core-synch-l1-2-0.dll " ), " WakeByAddressSingle" ));
139+ GetProcAddress (win32_get_win_core_synch_api_module ( ), " WakeByAddressSingle" ));
129140 if (wake_by_address_single != nullptr ) {
130141 wake_by_address_single (const_cast <__cxx_atomic_contention_t *>(__ptr));
131142 } else {
@@ -135,7 +146,7 @@ static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const vo
135146 } else {
136147 // WakeByAddressAll was added in Windows 8 (build 9200)
137148 static auto wake_by_address_all = reinterpret_cast <void (WINAPI*)(PVOID)>(
138- GetProcAddress (GetModuleHandleW ( L" api-ms-win-core-synch-l1-2-0.dll " ), " WakeByAddressAll" ));
149+ GetProcAddress (win32_get_win_core_synch_api_module ( ), " WakeByAddressAll" ));
139150 if (wake_by_address_all != nullptr ) {
140151 wake_by_address_all (const_cast <__cxx_atomic_contention_t *>(__ptr));
141152 } else {
0 commit comments