diff options
| author | Stefan Boberg <[email protected]> | 2025-10-29 09:35:25 +0100 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2025-10-29 09:35:25 +0100 |
| commit | 2e293bbbf17639471d6d570212a09d097801da66 (patch) | |
| tree | 1eb3d7e53952aee2ec8b3a2a43b839f3594de392 /src/zencore/thread.cpp | |
| parent | fix --zentrace=no compile errors (#616) (diff) | |
| download | zen-2e293bbbf17639471d6d570212a09d097801da66.tar.xz zen-2e293bbbf17639471d6d570212a09d097801da66.zip | |
fix for Latch race (#617)
Because the counter is decreased in `CountDown()` and subsequently checked against zero to determine if the completion event should be set:
`Latch::Wait` checks the counter against zero on entry and would exit early, before waiting on the completion event. This could then lead to the `Latch` instance being torn down before the `CountDown()` does a `Set()` which could then lead to unexpected and unwanted things happening.
Diffstat (limited to 'src/zencore/thread.cpp')
| -rw-r--r-- | src/zencore/thread.cpp | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/src/zencore/thread.cpp b/src/zencore/thread.cpp index 7bd21a229..9e3486e49 100644 --- a/src/zencore/thread.cpp +++ b/src/zencore/thread.cpp @@ -200,7 +200,7 @@ Event::Set() SetEvent(m_EventHandle); #else std::atomic_thread_fence(std::memory_order_acquire); - auto* Inner = (EventInner*)m_EventHandle; + auto* Inner = (EventInner*)m_EventHandle.load(); { std::unique_lock Lock(Inner->Mutex); Inner->bSet.store(true); @@ -216,7 +216,7 @@ Event::Reset() ResetEvent(m_EventHandle); #else std::atomic_thread_fence(std::memory_order_acquire); - auto* Inner = (EventInner*)m_EventHandle; + auto* Inner = (EventInner*)m_EventHandle.load(); { std::unique_lock Lock(Inner->Mutex); Inner->bSet.store(false); @@ -232,7 +232,7 @@ Event::Close() m_EventHandle = nullptr; #else std::atomic_thread_fence(std::memory_order_acquire); - auto* Inner = (EventInner*)m_EventHandle; + auto* Inner = (EventInner*)m_EventHandle.load(); { std::unique_lock Lock(Inner->Mutex); Inner->bSet.store(true); @@ -260,7 +260,7 @@ Event::Wait(int TimeoutMs) return (Result == WAIT_OBJECT_0); #else std::atomic_thread_fence(std::memory_order_acquire); - auto* Inner = reinterpret_cast<EventInner*>(m_EventHandle); + auto* Inner = reinterpret_cast<EventInner*>(m_EventHandle.load()); if (Inner->bSet.load()) { @@ -372,7 +372,7 @@ NamedEvent::Close() #if ZEN_PLATFORM_WINDOWS CloseHandle(m_EventHandle); #elif ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC - int Fd = int(intptr_t(m_EventHandle) & 0xffff'ffff); + int Fd = int(intptr_t(m_EventHandle.load()) & 0xffff'ffff); if (flock(Fd, LOCK_EX | LOCK_NB) == 0) { @@ -390,7 +390,7 @@ NamedEvent::Close() flock(Fd, LOCK_UN | LOCK_NB); close(Fd); - int Sem = int(intptr_t(m_EventHandle) >> 32); + int Sem = int(intptr_t(m_EventHandle.load()) >> 32); semctl(Sem, 0, IPC_RMID); } #endif @@ -408,7 +408,7 @@ NamedEvent::Set() return MakeErrorCodeFromLastError(); } #elif ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC - int Sem = int(intptr_t(m_EventHandle) >> 32); + int Sem = int(intptr_t(m_EventHandle.load()) >> 32); if (semctl(Sem, 0, SETVAL, 0) == -1) { return MakeErrorCodeFromLastError(); @@ -434,7 +434,7 @@ NamedEvent::Wait(int TimeoutMs) return (Result == WAIT_OBJECT_0); #elif ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC - int Sem = int(intptr_t(m_EventHandle) >> 32); + int Sem = int(intptr_t(m_EventHandle.load()) >> 32); int Result; struct sembuf SemOp = {}; |