Skip to content

Commit 899aed7

Browse files
author
Roger Sanders
committed
[libc++] Corrected loading/unloading of API set
1 parent 49efee9 commit 899aed7

File tree

1 file changed

+14
-3
lines changed

1 file changed

+14
-3
lines changed

libcxx/src/atomic.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
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+
110121
static 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

Comments
 (0)