BOOST_LOG_API bool once_block_sentry::enter_once_block() const { AcquireSRWLockExclusive(&g_OnceBlockMutex); once_block_flag volatile& flag = m_Flag; while (flag.status != once_block_flag::initialized) { if (flag.status == once_block_flag::uninitialized) { flag.status = once_block_flag::being_initialized; ReleaseSRWLockExclusive(&g_OnceBlockMutex); // Invoke the initializer block return false; } else { while (flag.status == once_block_flag::being_initialized) { BOOST_VERIFY(SleepConditionVariableSRW( &g_OnceBlockCond, &g_OnceBlockMutex, INFINITE, 0)); } } } ReleaseSRWLockExclusive(&g_OnceBlockMutex); return true; }
void qemu_cond_wait_impl(QemuCond *cond, QemuMutex *mutex, const char *file, const int line) { assert(cond->initialized); trace_qemu_mutex_unlock(mutex, file, line); SleepConditionVariableSRW(&cond->var, &mutex->lock, INFINITE, 0); trace_qemu_mutex_locked(mutex, file, line); }
// -------------------------------------------------------------------------------------- FUNCTION // -------------------------------------------------------------------------------------- FUNCTION void Monitor::Wait(XR_IN xr::Core::Mutex & mutex) const { if (SleepConditionVariableSRW((CONDITION_VARIABLE*)&mCondition, mutex.UnderlyingSystemObject(), INFINITE, 0) == FALSE) { uint32_t err = (uint32_t)GetLastError(); XR_ASSERT_ALWAYS_EQ_FM(err, ERROR_TIMEOUT, "SleepConditionVariableSRW Error 0x%8.8" XR_UINT32_PRINTX "!", err); } }
bool wait() { BOOL result = SleepConditionVariableSRW( &condition, &lock, INFINITE, 0 ); bool ret = false; if( result == TRUE ) { down(); ReleaseSRWLockExclusive( &lock ); ret = true; } return ret; }
BOOL ConsumeElement(int nThreadNum, int nRequestNum, HWND hWndLB) { // Get access to the queue to consume a new element AcquireSRWLockShared(&g_srwLock); // Fall asleep until there is something to read. // Check if, while it was asleep, // it was not decided that the thread should stop while (g_q.IsEmpty(nThreadNum) && !g_fShutdown) { // There was not a readable element AddText(hWndLB, TEXT("[%d] Nothing to process"), nThreadNum); // The queue is empty // --> Wait until a writer adds a new element to read // and come back with the lock acquired in shared mode SleepConditionVariableSRW(&g_cvReadyToConsume, &g_srwLock, INFINITE, CONDITION_VARIABLE_LOCKMODE_SHARED); } // When thread is exiting, the lock should be released for writer // and readers should be signaled through the condition variable if (g_fShutdown) { // Show that the current thread is exiting AddText(hWndLB, TEXT("[%d] bye bye"), nThreadNum); // Another writer thread might still be blocked on the lock // --> release it before exiting ReleaseSRWLockShared(&g_srwLock); // Notify other readers that it is time to exit // --> release readers WakeConditionVariable(&g_cvReadyToConsume); return(FALSE); } // Get the first new element CQueue::ELEMENT e; // Note: No need to test the return value since IsEmpty // returned FALSE g_q.GetNewElement(nThreadNum, e); // No need to keep the lock any longer ReleaseSRWLockShared(&g_srwLock); // Show result of consuming the element AddText(hWndLB, TEXT("[%d] Processing %d:%d"), nThreadNum, e.m_nThreadNum, e.m_nRequestNum); // A free slot is now available for writer threads to produce // --> wake up a writer thread WakeConditionVariable(&g_cvReadyToProduce); return(TRUE); }
_EXP_IMPL void __cdecl Event::wait() { AcquireSRWLockExclusive(reinterpret_cast<PSRWLOCK>(&m_lock)); while (!m_isSet) { SleepConditionVariableSRW(reinterpret_cast<PCONDITION_VARIABLE>(&m_cond), reinterpret_cast<PSRWLOCK>(&m_lock), INFINITE, 0); } ReleaseSRWLockExclusive(reinterpret_cast<PSRWLOCK>(&m_lock)); }
int __bctbx_WIN_cond_wait(bctbx_cond_t* hCond, bctbx_mutex_t * hMutex) { #ifdef BCTBX_WINDOWS_DESKTOP //gulp: this is not very atomic ! bug here ? __bctbx_WIN_mutex_unlock(hMutex); WaitForSingleObject(*hCond, INFINITE); __bctbx_WIN_mutex_lock(hMutex); #else SleepConditionVariableSRW(hCond, hMutex, INFINITE, 0); #endif return 0; }
int condvar_wait(struct condvar_handle *condvar, struct mutex_handle *mutex) { struct condvar_priv *priv = (struct condvar_priv *)condvar->priv; struct mutex_priv *mpriv = (struct mutex_priv *)mutex->priv; if (!SleepConditionVariableSRW(&priv->cond, &mpriv->lock, INFINITE, 0)) { return GetLastError(); } return 0; }
DWORD QueuePut (QUEUE_OBJECT *q, PVOID msg, DWORD msize, DWORD MaxWait) { AcquireSRWLockExclusive (&q->qGuard); if (q->msgArray == NULL) return 1; /* Queue has been destroyed */ while (QueueFull (q)) { if (!SleepConditionVariableSRW(&q->qNf, &q->qGuard, INFINITE, 0)) ReportError(_T("QueuePut failed. SleepConditionVariableCS."), 1, TRUE); } /* Put the message in the queue */ QueueInsert (q, msg, msize); /* Signal that the queue is not empty as we've inserted a message */ WakeConditionVariable (&q->qNe); ReleaseSRWLockExclusive (&q->qGuard); return 0; }
DWORD QueueGet (QUEUE_OBJECT *q, PVOID msg, DWORD msize, DWORD MaxWait) { AcquireSRWLockExclusive (&q->qGuard); if (q->msgArray == NULL) return 1; /* Queue has been destroyed */ while (QueueEmpty (q)) { if (!SleepConditionVariableSRW (&q->qNe, &q->qGuard, INFINITE, 0)) ReportError(_T("QueueGet failed. SleepConditionVariableCS."), 1, TRUE); } /* remove the message from the queue */ QueueRemove (q, msg, msize); /* Signal that the queue is not full as we've removed a message */ WakeConditionVariable (&q->qNf); ReleaseSRWLockExclusive (&q->qGuard); return 0; }
DWORD WINAPI WriterThread(PVOID pvParam) { int nThreadNum = PtrToUlong(pvParam); HWND hWndLB = GetDlgItem(g_hWnd, IDC_CLIENTS); for (int nRequestNum = 1; !g_fShutdown; nRequestNum++) { CQueue::ELEMENT e = { nThreadNum, nRequestNum }; // Require access for writing AcquireSRWLockExclusive(&g_srwLock); // If the queue is full, fall asleep as long as the condition variable // is not signaled // Note: During the wait for acquiring the lock, // a stop might have been received if (g_q.IsFull() & !g_fShutdown) { // No more room in the queue AddText(hWndLB, TEXT("[%d] Queue is full: impossible to add %d"), nThreadNum, nRequestNum); // --> Need to wait for a reader to empty a slot before acquiring // the lock again SleepConditionVariableSRW(&g_cvReadyToProduce, &g_srwLock, INFINITE, 0); } // Other writer threads might still be blocked on the lock // --> Release the lock and notify the remaining writer threads to quit if (g_fShutdown) { // Show that the current thread is exiting AddText(hWndLB, TEXT("[%d] bye bye"), nThreadNum); // No need to keep the lock any longer ReleaseSRWLockExclusive(&g_srwLock); // Signal other blocked writers threads that it is time to exit WakeAllConditionVariable(&g_cvReadyToProduce); // Bye bye return(0); } else { // Add the new ELEMENT into the queue g_q.AddElement(e); // Show result of processing element AddText(hWndLB, TEXT("[%d] Adding %d"), nThreadNum, nRequestNum); // No need to keep the lock any longer ReleaseSRWLockExclusive(&g_srwLock); // Signal reader threads that there is an element to consume WakeAllConditionVariable(&g_cvReadyToConsume); // Wait before adding a new element Sleep(1500); } } // Show that the current thread is exiting AddText(hWndLB, TEXT("[%d] bye bye"), nThreadNum); return(0); }
// A function responsible for releasing a SlimReadWriter lock and putting the calling thread to sleep. inline bool ConditionVariable::sleep( SRWLOCK& slim_read_writer_lock , const DWORD milliseconds , bool shared ) { return ( SleepConditionVariableSRW(&_variable,&slim_read_writer_lock,milliseconds, ( shared ? CONDITION_VARIABLE_LOCKMODE_SHARED : 0 ) ) > FALSE ? true : false ); };