MAGMA_DLLPORT int MAGMA_CDECL pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) { int last; if ( *mutex == PTHREAD_MUTEX_INITIALIZER ) pthread_mutex_check_for_static_initialization( mutex ); /* Avoid race condition on waiting thread counter. */ EnterCriticalSection(&cond->cs); cond->waitCount++; LeaveCriticalSection(&cond->cs); /* Releases _atomically_ the mutex and wait on the semaphore until pthread_cond_signal() or pthread_cond_broadcast() are called (by another thread). */ SignalObjectAndWait(*mutex, cond->hSem, INFINITE, FALSE); /* Avoid race condition on waiting thread counter. */ EnterCriticalSection(&cond->cs); cond->waitCount--; /* this thread doesn't wait any more */ /* if this is the last thread to have waited */ last = cond->waitCount == 0; LeaveCriticalSection(&cond->cs); /* If this thread is the last waiter thread during this particular broadcast then let all the other threads proceed. */ if (last) /* This call ensures that two things happen atomically: signaling the hEvt event and waiting until "mutex" can be acquired. */ SignalObjectAndWait(cond->hEvt, *mutex, INFINITE, FALSE); else WaitForSingleObject(*mutex, INFINITE); /* Upon return, this thread has to own "mutex". */ return 0; }
int pthread_cond_timedwait (pthread_cond_t* cv, pthread_mutex_t* external_mutex, timespec* abstime) { int last_waiter; DWORD timeout = 0; //struct timeval now; //timespec timenow; //gettimeofday(&now, NULL); //timenow.tv_sec = now.tv_sec; //timenow.tv_nsec = now.tv_usec * 1000; //timeout = (DWORD)((abstime->tv_sec - timenow.tv_sec) * 1000 + (abstime->tv_nsec - timenow.tv_nsec) / 1000000 + 5); timeout = (DWORD)((abstime->tv_sec) * 1000 + (abstime->tv_nsec) / 1000000 + 5); EnterCriticalSection (&cv->waiters_count_lock_); cv->waiters_count_++; LeaveCriticalSection (&cv->waiters_count_lock_); SignalObjectAndWait (*external_mutex, cv->sema_, timeout, FALSE); EnterCriticalSection (&cv->waiters_count_lock_); cv->waiters_count_--; last_waiter = (cv->was_broadcast_ && cv->waiters_count_ == 0); LeaveCriticalSection (&cv->waiters_count_lock_); if (last_waiter) SignalObjectAndWait (cv->waiters_done_, *external_mutex, INFINITE, FALSE); else WaitForSingleObject (*external_mutex, INFINITE); }
status_t wait(WinCondition* condState, HANDLE hMutex, nsecs_t* abstime) { // Increment the wait count, avoiding race conditions. EnterCriticalSection(&condState->waitersCountLock); condState->waitersCount++; //printf("+++ wait: incr waitersCount to %d (tid=%ld)\n", // condState->waitersCount, getThreadId()); LeaveCriticalSection(&condState->waitersCountLock); DWORD timeout = INFINITE; if (abstime) { nsecs_t reltime = *abstime - systemTime(); if (reltime < 0) reltime = 0; timeout = reltime/1000000; } // Atomically release the external mutex and wait on the semaphore. DWORD res = SignalObjectAndWait(hMutex, condState->sema, timeout, FALSE); //printf("+++ wait: awake (tid=%ld)\n", getThreadId()); // Reacquire lock to avoid race conditions. EnterCriticalSection(&condState->waitersCountLock); // No longer waiting. condState->waitersCount--; // Check to see if we're the last waiter after a broadcast. bool lastWaiter = (condState->wasBroadcast && condState->waitersCount == 0); //printf("+++ wait: lastWaiter=%d (wasBc=%d wc=%d)\n", // lastWaiter, condState->wasBroadcast, condState->waitersCount); LeaveCriticalSection(&condState->waitersCountLock); // If we're the last waiter thread during this particular broadcast // then signal broadcast() that we're all awake. It'll drop the // internal mutex. if (lastWaiter) { // Atomically signal the "waitersDone" event and wait until we // can acquire the internal mutex. We want to do this in one step // because it ensures that everybody is in the mutex FIFO before // any thread has a chance to run. Without it, another thread // could wake up, do work, and hop back in ahead of us. SignalObjectAndWait(condState->waitersDone, condState->internalMutex, INFINITE, FALSE); } else { // Grab the internal mutex. WaitForSingleObject(condState->internalMutex, INFINITE); } // Release the internal and grab the external. ReleaseMutex(condState->internalMutex); WaitForSingleObject(hMutex, INFINITE); return res == WAIT_OBJECT_0 ? NO_ERROR : -1; }
int pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex, const struct timespec * abstime) { DWORD res = 0; int last_waiter = 0; PThreadCond * p = (PThreadCond *)*cond; DWORD timeout = 0; struct timespec timenow; if (clock_gettime(p->clock_id, &timenow)) return errno; if (abstime->tv_sec < timenow.tv_sec) return ETIMEDOUT; if (abstime->tv_sec == timenow.tv_sec) { if (abstime->tv_nsec <= timenow.tv_nsec) return ETIMEDOUT; } timeout = (DWORD)((abstime->tv_sec - timenow.tv_sec) * 1000 + (abstime->tv_nsec - timenow.tv_nsec) / 1000000 + 5); EnterCriticalSection(&p->waiters_count_lock); p->waiters_count++; LeaveCriticalSection(&p->waiters_count_lock); /* This call atomically releases the mutex and waits on the */ /* semaphore until <pthread_cond_signal> or <pthread_cond_broadcast> */ /* are called by another thread. */ res = SignalObjectAndWait(*mutex, p->sema, timeout, FALSE); if (res == WAIT_FAILED) return set_win32_errno(GetLastError()); /* Re-acquire lock to avoid race conditions. */ EnterCriticalSection(&p->waiters_count_lock); /* We're no longer waiting... */ p->waiters_count--; /* Check to see if we're the last waiter after <pthread_cond_broadcast>. */ last_waiter = p->was_broadcast && p->waiters_count == 0; LeaveCriticalSection(&p->waiters_count_lock); /* If we're the last waiter thread during this particular broadcast */ /* then let all the other threads proceed. */ if (last_waiter) { /* This call atomically signals the <waiters_done> event and waits until */ /* it can acquire the <mutex>. This is required to ensure fairness. */ DWORD err = SignalObjectAndWait(p->waiters_done, *mutex, INFINITE, FALSE); if (err == WAIT_FAILED) return set_win32_errno(GetLastError()); } else { /* Always regain the external mutex since that's the guarantee we */ /* give to our callers. */ DWORD err = WaitForSingleObject(*mutex, INFINITE); if (err == WAIT_FAILED) return set_win32_errno(GetLastError()); } if (res == WAIT_TIMEOUT) return errno = ETIMEDOUT; assert(res == WAIT_OBJECT_0); return 0; }
int pthread_cond_waitImpl (pthread_cond_t *cv, pthread_mutex_t *external_mutex, const struct timespec *abstime, bool infinite) { int last_waiter; DWORD dwMilliseconds = INFINITE; // Avoid race conditions. EnterCriticalSection (&cv->waiters_count_lock_); cv->waiters_count_++; LeaveCriticalSection (&cv->waiters_count_lock_); // This call atomically releases the mutex and waits on the // semaphore until <pthread_cond_signal> or <pthread_cond_broadcast> // are called by another thread. if (!infinite && abstime != NULL) { dwMilliseconds = abstime->tv_sec * 1000 + abstime->tv_nsec / 1000000; } SignalObjectAndWait (*external_mutex, cv->sema_, dwMilliseconds, FALSE); // Reacquire lock to avoid race conditions. EnterCriticalSection (&cv->waiters_count_lock_); // We're no longer waiting... cv->waiters_count_--; // Check to see if we're the last waiter after <pthread_cond_broadcast>. last_waiter = cv->was_broadcast_ && cv->waiters_count_ == 0; LeaveCriticalSection (&cv->waiters_count_lock_); // If we're the last waiter thread during this particular broadcast // then let all the other threads proceed. if (last_waiter) // This call atomically signals the <waiters_done_> event and waits until // it can acquire the <external_mutex>. // This is required to ensure fairness. SignalObjectAndWait (cv->waiters_done_, *external_mutex, INFINITE, FALSE); else { // Always regain the external mutex since that's the guarantee we // give to our callers. /* fprintf(stderr, "%s: WaitForSingleObject...\n", __func__); */ WaitForSingleObject (*external_mutex, INFINITE); /* fprintf(stderr, "... %s: WaitForSingleObject\n", __func__); */ } return 0; }
/******************************************************************************************** Function : WaitTimeout DateTime : 2010/6/10 9:42 Description : 等待条件变量,超时返回 Input : INT mseconds:等待的时间,毫秒 Output : NULL Return : 返回0成功,其他表示失败 Note : // 备注 ********************************************************************************************/ INT CGSCond::WaitTimeout(INT mseconds) { #ifdef _WIN32 INT iRet = -1; if (WaitForSingleObject(m_mutex,mseconds) == WAIT_OBJECT_0) { iRet = SignalObjectAndWait(m_mutex, m_GSCond,mseconds,FALSE) == WAIT_OBJECT_0 ? 0 : -1; ResetEvent(m_GSCond); } return iRet; #elif _LINUX INT32 iRet = 0; struct timeval struTimeVal; struct timespec struTimeSpec; gettimeofday(&struTimeVal, NULL); struTimeSpec.tv_sec = mseconds/1000; struTimeSpec.tv_nsec =1000L *(struTimeVal.tv_usec+(mseconds-struTimeSpec.tv_sec*1000)*1000L); struTimeSpec.tv_sec += struTimeVal.tv_sec; m_CondMutex->Lock(); iRet = pthread_cond_timedwait( &m_GSCond, &m_CondMutex->m_GSMutex, &struTimeSpec); m_CondMutex->Unlock(); return iRet; #endif }
void Gamepad_Windows::destroy() { if (_reader_thread_handle) { DWORD errcode = ERROR_OBJECT_NOT_FOUND; if (_input_received_event) SetEvent(_input_received_event); if (_thread_exit_event) errcode = SignalObjectAndWait(_thread_exit_event, _reader_thread_handle, 1000, false); if (errcode) TerminateThread(_reader_thread_handle, errcode); CloseHandle(_reader_thread_handle); _reader_thread_handle = NULL; } if (_input_received_event) { CloseHandle(_input_received_event); _input_received_event = NULL; } if (_thread_exit_event) { CloseHandle(_thread_exit_event); _thread_exit_event = NULL; } if (_preparsed) { hid.HidD_FreePreparsedData(_preparsed); _preparsed = NULL; } if (_notif_handle != NULL) { UnregisterDeviceNotification(_notif_handle); _notif_handle = NULL; } if (_handle != INVALID_HANDLE_VALUE) { CloseHandle(_handle); _handle = INVALID_HANDLE_VALUE; } }
void qemu_cond_signal(QemuCond *cond) { DWORD result; /* * Signal only when there are waiters. cond->waiters is * incremented by pthread_cond_wait under the external lock, * so we are safe about that. */ if (cond->waiters == 0) { return; } /* * Waiting threads decrement it outside the external lock, but * only if another thread is executing pthread_cond_broadcast and * has the mutex. So, it also cannot be decremented concurrently * with this particular access. */ cond->target = cond->waiters - 1; result = SignalObjectAndWait(cond->sema, cond->continue_event, INFINITE, FALSE); if (result == WAIT_ABANDONED || result == WAIT_FAILED) { error_exit(GetLastError(), __func__); } }
void CPipeServer::Close() { // close thread handle EnterCriticalSection(&m_sInitSafe); m_bWorking= false; DWORD dwRes= WAIT_OBJECT_0 +1; if (m_hThread) { if (m_hDone) dwRes= SignalObjectAndWait(m_hDone, m_hThread, 2000, FALSE); if (dwRes != WAIT_OBJECT_0) { TerminateThread(m_hThread, 0); DeleteCriticalSection(&m_sPipeSafe); // we do this so that we can enter cc after close, in case it was terminated in cc. InitializeCriticalSection(&m_sPipeSafe); } } for (size_t i= 0; i<m_aPipes.size();++i) { m_pcMemPool->PoolRelease(m_aPipes[i]->pRead); DecreaseQueue(m_aPipes[i]->ClearQueue()); delete m_aPipes[i]; } m_aPipes.clear(); if (m_hDone) CloseHandle(m_hDone); if (m_hThread) CloseHandle(m_hThread); m_hThread= NULL; m_hDone= NULL; m_pcDevice= NULL; m_pcLogBuffer= NULL; m_sStream.str(_T("")); LeaveCriticalSection(&m_sInitSafe); }
bool_t SIGNAL_WAIT( SIGNAL_T *ref, MUTEX_T *mu_ref, time_d abs_secs ) { DWORD rc; long ms; if (abs_secs<0.0) ms= INFINITE; else if (abs_secs==0.0) ms= 0; else { ms= (long) ((abs_secs - now_secs())*1000.0 + 0.5); // If the time already passed, still try once (ms==0). A short timeout // may have turned negative or 0 because of the two time samples done. // if (ms<0) ms= 0; } // Unlock and start a wait, atomically (like condition variables do) // rc= SignalObjectAndWait( *mu_ref, // "object to signal" (unlock) *ref, // "object to wait on" ms, FALSE ); // not alertable // All waiting locks are woken here; each competes for the lock in turn. // // Note: We must get the lock even if we've timed out; it makes upper // level code equivalent to how PThread does it. // MUTEX_LOCK(mu_ref); if (rc==WAIT_TIMEOUT) return FALSE; if (rc!=0) FAIL( "SignalObjectAndWait", rc ); return TRUE; }
bool sys::ConditionVarDataWin32::wait(HANDLE externalMutex, double timeout) { if (timeout == 0) { wait(externalMutex); return true; } // Increment # waiting { const ScopedCriticalSection lock(mNumWaitersCS); ++mNumWaiters; } // Atomically release the mutex and wait on the semaphore until signal() // or broadcast() are called by another thread or we time out switch (SignalObjectAndWait(externalMutex, mSemaphore, static_cast<DWORD>(timeout * 1000), FALSE)) { case WAIT_OBJECT_0: waitImpl(externalMutex); return true; case WAIT_TIMEOUT: return false; default: throw sys::SystemException("SignalObjectAndWait() failed"); } }
void sys::ConditionVarDataWin32::waitImpl(HANDLE externalMutex) { // Mark that we're no longer waiting // If we woke up via broadcast(), determine if we're the last waiter bool lastWaiter; { const ScopedCriticalSection lock(mNumWaitersCS); --mNumWaiters; lastWaiter = (mWasBroadcast && mNumWaiters == 0); } if (lastWaiter) { // Atomically signals the mWaitersAreDone event and waits until it can // acquire the external mutex. This is used to ensure fairness. /// @note Fairness relies on the fact that Windows NT mutex requests /// are queued in FIFO order. As a result, all waiting threads /// will acquire the external mutex before any of them can /// reacquire it a second time. /// Need the atomicity of SignalObjectAndWait() here to ensure /// that the last thread gets his chance to wait on the /// external mutex. SignalObjectAndWait(mWaitersAreDone, externalMutex, INFINITE, FALSE); } else { // We need to wait until we get the external mutex back WaitForSingleObject(externalMutex, INFINITE); } }
/************************************************************** * * rngBlkPut - put element into a blocking ring buffer * * * This routine copies n elements from <buffer> into blocking ring buffer *<rngd>. The specified number of elements will be put into the ring buffer. *If there is insuffient room the calling task will BLOCK. * * RETURNS: * The number of elements actually put into ring buffer. * * Author Greg Brissey 5/26/94 */ int rngBlkPut(RINGBLK_ID rngd,register long* buffer,register int size) /* RINGBLK_ID rngd; blocking ring buffer to put data into */ /* long* buffer; buffer to get data from */ /* int size; number of elements to put */ { register int fromP; int fbytes; register int result,i; DWORD winStatus; winStatus = WaitForSingleObject(rngd->hMutex, INFINITE); if (winStatus == WAIT_FAILED) { return -1; } while( (fbytes = ( ( (result = ((rngd->pFromBuf - rngd->pToBuf) - 1)) < 0) ? result + rngd->bufSize : result ) ) < size) { /* printf("rngBlkPut: semGive OK2Read., free bytes: %d \n",fbytes); */ rngd->writeBlocked = TRUE; if (rngd->readBlocked) { /* if read blocked, */ rngd->readBlocked = FALSE; SetEvent(rngd->hSyncOk2ReadEvent); } while( rngd->writeBlocked) { SignalObjectAndWait(rngd->hMutex, rngd->hSyncOk2WriteEvent, INFINITE, FALSE); winStatus = WaitForSingleObject(rngd->hMutex, INFINITE); if (winStatus == WAIT_FAILED) { return -1; } } } for (i = 0; i < size; i++) { /* this macro inlines the code for speed */ RNG_LONG_PUT(rngd, (buffer[i]), fromP); } /* if I just wrote something into the ring buffer & read is block */ /* release the reading because there is now room in the buffer */ if ( (rngd->readBlocked) && ( rngBlkNElem(rngd) > rngd->blkTilNentries) ) { /* printf("rngBlkGet: OK2Write given.\n"); */ rngd->readBlocked = FALSE; SetEvent(rngd->hSyncOk2ReadEvent); } ReleaseMutex(rngd->hMutex); return( size ); }
int ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond, ldap_pvt_thread_mutex_t *mutex ) { SignalObjectAndWait( *mutex, *cond, INFINITE, FALSE ); WaitForSingleObject( *mutex, INFINITE ); return( 0 ); }
void CondVar::Wait(Mutex& externalMutex) { #ifdef WIN32 SignalObjectAndWait(externalMutex.mutex,condVarEvent,INFINITE,FALSE); externalMutex.Lock(); #else pthread_cond_wait(&condVar,&externalMutex.mutex); #endif }
int pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex) { DWORD res = 0; int last_waiter = 0; PThreadCond * p = (PThreadCond *)*cond; EnterCriticalSection(&p->waiters_count_lock); p->waiters_count++; LeaveCriticalSection(&p->waiters_count_lock); /* This call atomically releases the mutex and waits on the */ /* semaphore until <pthread_cond_signal> or <pthread_cond_broadcast> */ /* are called by another thread. */ res = SignalObjectAndWait(*mutex, p->sema, INFINITE, FALSE); if (res == WAIT_FAILED) return set_win32_errno(GetLastError()); /* Re-acquire lock to avoid race conditions. */ EnterCriticalSection(&p->waiters_count_lock); /* We're no longer waiting... */ p->waiters_count--; /* Check to see if we're the last waiter after <pthread_cond_broadcast>. */ last_waiter = p->was_broadcast && p->waiters_count == 0; LeaveCriticalSection(&p->waiters_count_lock); /* If we're the last waiter thread during this particular broadcast */ /* then let all the other threads proceed. */ if (last_waiter) { /* This call atomically signals the <waiters_done_> event and waits until */ /* it can acquire the <mutex>. This is required to ensure fairness. */ DWORD err = SignalObjectAndWait(p->waiters_done, *mutex, INFINITE, FALSE); if (err == WAIT_FAILED) return set_win32_errno(GetLastError()); } else { /* Always regain the external mutex since that's the guarantee we */ /* give to our callers. */ DWORD err = WaitForSingleObject(*mutex, INFINITE); if (err == WAIT_FAILED) return set_win32_errno(GetLastError()); } assert(res == WAIT_OBJECT_0); return 0; }
void SerializeEnter() { if(SignalObjectAndWait(gWaitingSemaphore, gAvailableSemaphore, INFINITE, FALSE) == WAIT_OBJECT_0) { //We got hold of the "available" semaphore. Decrement the "waiting" semaphore //to indicate that we are not waiting anymore WaitForSingleObject(gWaitingSemaphore, INFINITE); gInside = true; } }
bool Send(UOMessage msg, UINT arg1, UINT arg2, UINT arg3) { shared->msgOut[0] = msg; shared->msgOut[1] = arg1; shared->msgOut[2] = arg2; shared->msgOut[3] = arg3; if (SignalObjectAndWait(sentOut, handledOut, INFINITE, FALSE)) return false; return shared->msgOut[0] == 1; }
// sleep this thread, waiting for condition signal void Wait( void ) { #if defined( HAVE_POSIX_THREAD ) pthread_cond_wait( &mCondition, &mMutex ); #elif defined( HAVE_WIN32_THREAD ) // atomically release mutex and wait on condition, // then re-acquire the mutex SignalObjectAndWait( mMutex, mCondition, INFINITE, false ); WaitForSingleObject( mMutex, INFINITE ); #endif }
bool SendData(UOMessage msg, LPVOID data, UINT len) { memcpy(shared->dataOut, data, len); shared->msgOut[0] = msg; shared->msgOut[1] = len; if (SignalObjectAndWait(sentOut, handledOut, INFINITE, FALSE)) return false; if (shared->msgOut[0] == 2) memcpy(data, shared->dataOut, len); return shared->msgOut[0] == 1; }
void gcore::Condition::wait(gcore::Mutex &mtx) { details::ConditionData *cond = (details::ConditionData*)&(mData[0]); EnterCriticalSection(&cond->waiterCountLock); cond->waiterCount++; LeaveCriticalSection(&cond->waiterCountLock); SignalObjectAndWait(*((HANDLE*)&(mtx.mData[0])), cond->sema, INFINITE, FALSE) EnterCriticalSection(&cond->waiterCountLock); cond->waiterCount--; bool lastWaiter = (cond->wasBroadcast && cond->waiterCount==0); LeaveCriticalSection(&cond->waiterCountLock); if (lastWaiter) { SignalObjectAndWait(cond->waiterDone, *((HANDLE*)&(mtx.mData[0])), INFINITE, FALSE); } else { WaitForSingleObject(*((HANDLE*)&(mtx.mData[0])), INFINITE); } }
int pthread_cond_wait (pthread_cond_t *cv, pthread_mutex_t *external_mutex) { int last_waiter; // Avoid race conditions. EnterCriticalSection (&cv->waiters_count_lock_); cv->waiters_count_++; LeaveCriticalSection (&cv->waiters_count_lock_); // This call atomically releases the mutex and waits on the // semaphore until <pthread_cond_signal> or <pthread_cond_broadcast> // are called by another thread. SignalObjectAndWait (*external_mutex, cv->sema_, INFINITE, FALSE); // Reacquire lock to avoid race conditions. EnterCriticalSection (&cv->waiters_count_lock_); // We're no longer waiting... cv->waiters_count_--; // Check to see if we're the last waiter after <pthread_cond_broadcast>. last_waiter = cv->was_broadcast_ && cv->waiters_count_ == 0; LeaveCriticalSection (&cv->waiters_count_lock_); // If we're the last waiter thread during this particular broadcast // then let all the other threads proceed. if (last_waiter) // This call atomically signals the <waiters_done_> event and waits until // it can acquire the <external_mutex>. This is required to ensure fairness. SignalObjectAndWait (cv->waiters_done_, *external_mutex, INFINITE, FALSE); else // Always regain the external mutex since that's the guarantee we // give to our callers. WaitForSingleObject (*external_mutex, INFINITE); // Temparary code in order not to notice warning... return 0; }
bool TimerManager::stop() { Locker lock(m_mutex); if(m_isStop) { return false; } m_isStop = true; // スレッド停止待ち ResetEvent(m_eventStop); SignalObjectAndWait(m_mutex, m_eventStop, INFINITE, FALSE); return true; }
static int profile_off (struct profinfo *p) { if (p->profthr) { SignalObjectAndWait (p->quitevt, p->profthr, INFINITE, FALSE); CloseHandle (p->quitevt); CloseHandle (p->profthr); } if (p->targthr) CloseHandle (p->targthr); return 0; }
int airThreadCondWait(airThreadCond *cond, airThreadMutex *mutex) { int last; /* increment count */ EnterCriticalSection(&(cond->lock)); /* avoid race conditions */ cond->count++; LeaveCriticalSection(&(cond->lock)); /* atomically release the mutex and wait on the semaphore until airThreadCondSignal or airThreadCondBroadcast are called by another thread */ if (WAIT_FAILED == SignalObjectAndWait(mutex->handle, cond->sema, INFINITE, FALSE)) { return 1; } /* reacquire lock to avoid race conditions */ EnterCriticalSection(&(cond->lock)); /* we're no longer waiting... */ cond->count--; /* check to see if we're the last waiter after airThreadCondBroadcast */ last = (cond->broadcast && 0 == cond->count); LeaveCriticalSection(&(cond->lock)); /* if we're the last waiter thread during this particular broadcast then let all the other threads proceed */ if (last) { /* atomically signal the done event and waits until we can acquire the mutex (this is required to ensure fairness) */ if (WAIT_FAILED == SignalObjectAndWait(cond->done, mutex->handle, INFINITE, FALSE)) { return 1; } } else { /* regain the external mutex since that's the guarantee to our callers */ if (WAIT_FAILED == WaitForSingleObject(mutex->handle, INFINITE)) { return 1; } } return 0; }
void wait(cybozu::Mutex& mutex) { #ifdef _WIN32 EnterCriticalSection(&waiterNumLock_); waiterNum_++; LeaveCriticalSection(&waiterNumLock_); SignalObjectAndWait(mutex.hdl_, sema_, INFINITE, FALSE); EnterCriticalSection(&waiterNumLock_); waiterNum_--; int last_waiter = wasBroadcast_ && waiterNum_ == 0; LeaveCriticalSection (&waiterNumLock_); if (last_waiter) { SignalObjectAndWait(waiterDone_, mutex.hdl_, INFINITE, FALSE); } else { WaitForSingleObject(mutex.hdl_, INFINITE); } #else pthread_cond_wait(&cv_, &mutex.hdl_); #endif }
bool gcore::Condition::timedWait(gcore::Mutex &mtx, unsigned long ms) { details::ConditionData *cond = (details::ConditionData*)&(mData[0]); EnterCriticalSection(&cond->waiterCountLock); cond->waiterCount++; LeaveCriticalSection(&cond->waiterCountLock); bool timedout = SignalObjectAndWait(*((HANDLE*)&(mtx.mData[0])), cond->sema, ms, FALSE) == WAIT_OBJET_0; EnterCriticalSection(&cond->waiterCountLock); cond->waiterCount--; bool lastWaiter = (!timedout && cond->wasBroadcast && cond->waiterCount==0); LeaveCriticalSection(&cond->waiterCountLock); if (lastWaiter) { SignalObjectAndWait(cond->waiterDone, *((HANDLE*)&(mtx.mData[0])), INFINITE, FALSE); } else { WaitForSingleObject(*((HANDLE*)&(mtx.mData[0])), INFINITE); } return !timedout; }
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mux) { int x, last; pthread_mutex_lock(&cond->lock); cond->waiters++; pthread_mutex_unlock(&cond->lock); // this does a pthread_mutex_unlock on mux x = SignalObjectAndWait(mux->handle, cond->queue, INFINITE, FALSE); assert(x == 0); pthread_mutex_lock(&cond->lock); cond->waiters--; last = cond->broadcast && cond->waiters == 0; pthread_mutex_unlock(&cond->lock); if(last) SignalObjectAndWait(cond->done, mux->handle, INFINITE, FALSE); else pthread_mutex_lock(mux); return 0; }
DWORD WINAPI worker_wait (LPVOID _data) { BOOL bExit; LPWORKER lpWorker; lpWorker = (LPWORKER )_data; bExit = FALSE; #ifdef DBUG dbug_print("Worker %x starting", lpWorker); #endif while ( !bExit && SignalObjectAndWait( lpWorker->hWorkerReady, lpWorker->hCommandReady, INFINITE, TRUE) == WAIT_OBJECT_0) { #ifdef DBUG dbug_print("Worker %x running", lpWorker); #endif switch (lpWorker->ECommand) { case WORKER_CMD_NONE: break; case WORKER_CMD_EXEC: if (lpWorker->hJobFunc != NULL) { SetEvent(lpWorker->hJobStarted); lpWorker->hJobFunc(lpWorker->hJobStop, lpWorker->lpJobUserData); SetEvent(lpWorker->hJobDone); }; break; case WORKER_CMD_STOP: bExit = TRUE; break; } }; #ifdef DBUG dbug_print("Worker %x exiting", lpWorker); #endif return 0; }
DWORD QueuePut (QUEUE_OBJECT *q, PVOID msg, DWORD mSize, DWORD maxWait) { WaitForSingleObject (q->qGuard, INFINITE); if (q->msgArray == NULL) return 1; /* Queue has been destroyed */ while (QueueFull (q)) { SignalObjectAndWait (q->qGuard, q->qNf, INFINITE, FALSE); WaitForSingleObject (q->qGuard, INFINITE); } /* Put the message in the queue */ QueueInsert (q, msg, mSize); /* Signal that the queue is not empty as we've inserted a message */ PulseEvent (q->qNe); ReleaseMutex (q->qGuard); return 0; }