@@ -108,24 +108,29 @@ static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const vo
108108
109109#elif defined(_WIN32)
110110
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.
111+ static void * win32_get_synch_api_function ( const char * function_name ) {
112+ // Attempt to load the API set. Note that HMODULE is documented as being a pointer type , which means we can safely use
113+ // std::unique_ptr here as a wrapper for the handle, with a destructor freeing the handle when this module is
114+ // unloaded.
115115 // https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types
116116 // https://devblogs.microsoft.com/oldnewthing/20180307-00/?p=98175
117117 static auto module_handle = std::unique_ptr<std::remove_pointer<HMODULE>::type, decltype (&FreeLibrary)>(
118118 LoadLibraryW (L" api-ms-win-core-synch-l1-2-0.dll" ), &FreeLibrary);
119- return module_handle.get ();
119+ if (!module_handle) {
120+ return nullptr ;
121+ }
122+
123+ // Attempt to locate the function in the API and return the result to the caller. Note that the NULL return from this
124+ // method is documented as being interchangeable with nullptr.
125+ // https://devblogs.microsoft.com/oldnewthing/20180307-00/?p=98175
126+ return GetProcAddress (module_handle.get (), function_name);
120127}
121128
122129static void
123130__libcpp_platform_wait_on_address (__cxx_atomic_contention_t const volatile * __ptr, __cxx_contention_t __val) {
124131 // WaitOnAddress was added in Windows 8 (build 9200)
125132 static auto wait_on_address = reinterpret_cast <BOOL (WINAPI*)(volatile void *, PVOID, SIZE_T, DWORD)>(
126- (win32_get_win_core_synch_api_module () != NULL
127- ? GetProcAddress (win32_get_win_core_synch_api_module (), " WaitOnAddress" )
128- : nullptr ));
133+ win32_get_synch_api_function (" WaitOnAddress" ));
129134 if (wait_on_address != nullptr ) {
130135 wait_on_address (const_cast <__cxx_atomic_contention_t *>(__ptr), &__val, sizeof (__val), INFINITE);
131136 } else {
@@ -138,10 +143,8 @@ __libcpp_platform_wait_on_address(__cxx_atomic_contention_t const volatile* __pt
138143static void __libcpp_platform_wake_by_address (__cxx_atomic_contention_t const volatile * __ptr, bool __notify_one) {
139144 if (__notify_one) {
140145 // WakeByAddressSingle was added in Windows 8 (build 9200)
141- static auto wake_by_address_single = reinterpret_cast <void (WINAPI*)(PVOID)>(
142- (win32_get_win_core_synch_api_module () != NULL
143- ? GetProcAddress (win32_get_win_core_synch_api_module (), " WakeByAddressSingle" )
144- : nullptr ));
146+ static auto wake_by_address_single =
147+ reinterpret_cast <void (WINAPI*)(PVOID)>(win32_get_synch_api_function (" WakeByAddressSingle" ));
145148 if (wake_by_address_single != nullptr ) {
146149 wake_by_address_single (const_cast <__cxx_atomic_contention_t *>(__ptr));
147150 } else {
@@ -150,10 +153,8 @@ static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const vo
150153 }
151154 } else {
152155 // WakeByAddressAll was added in Windows 8 (build 9200)
153- static auto wake_by_address_all = reinterpret_cast <void (WINAPI*)(PVOID)>(
154- (win32_get_win_core_synch_api_module () != NULL
155- ? GetProcAddress (win32_get_win_core_synch_api_module (), " WakeByAddressAll" )
156- : nullptr ));
156+ static auto wake_by_address_all =
157+ reinterpret_cast <void (WINAPI*)(PVOID)>(win32_get_synch_api_function (" WakeByAddressAll" ));
157158 if (wake_by_address_all != nullptr ) {
158159 wake_by_address_all (const_cast <__cxx_atomic_contention_t *>(__ptr));
159160 } else {
0 commit comments