[libcxx-commits] [libcxx] [libc++] Fix semaphore timed wait hanging on Windows (PR #180398)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Wed Feb 11 14:47:19 PST 2026


================
@@ -181,22 +189,31 @@ static void* win32_get_synch_api_function(const char* function_name) {
   return reinterpret_cast<void*>(GetProcAddress(module_handle, function_name));
 }
 
-template <std::size_t _Size>
-static void __platform_wait_on_address(void const* __ptr, void const* __val, uint64_t __timeout_ns) {
+template <std::size_t _Size, class MaybeTimeout>
+static void __platform_wait_on_address(void const* __ptr, void const* __val, MaybeTimeout maybe_timeout_ns) {
   static_assert(_Size == 8, "Can only wait on 8 bytes value");
   // WaitOnAddress was added in Windows 8 (build 9200)
   static auto wait_on_address =
       reinterpret_cast<BOOL(WINAPI*)(void*, PVOID, SIZE_T, DWORD)>(win32_get_synch_api_function("WaitOnAddress"));
   if (wait_on_address != nullptr) {
-    wait_on_address(const_cast<void*>(__ptr),
-                    const_cast<void*>(__val),
-                    _Size,
-                    __timeout_ns == 0 ? INFINITE : static_cast<DWORD>(__timeout_ns / 1'000'000));
+    auto timeout_ms = [&]() -> DWORD {
+      if constexpr (is_same_v<MaybeTimeout, NoTimeout>) {
+        return INFINITE;
+      } else {
+        auto ms = maybe_timeout_ns / 1'000'000;
+        if (ms == 0 && maybe_timeout_ns > 100'000)
+          // Round up to 1ms if requested between 100us - 1ms
+          return 1;
+
+        return ms > static_cast<uint64_t>(INFINITE) ? INFINITE : static_cast<DWORD>(ms);
----------------
ldionne wrote:

Maybe `min(static_cast<uint64_t>(INFINITE), ms)`? This isn't significantly better but I think it works.

https://github.com/llvm/llvm-project/pull/180398


More information about the libcxx-commits mailing list