Beispiel #1
0
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;
}
Beispiel #2
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;
 }
Beispiel #4
0
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;
}
Beispiel #5
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;
}
Beispiel #6
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
}
Beispiel #7
0
 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__);
    }
}
Beispiel #9
0
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);
}
Beispiel #10
0
  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;
  }
Beispiel #11
0
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");
    }
}
Beispiel #12
0
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);
    }
}
Beispiel #13
0
/**************************************************************
*
* 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 );
}
Beispiel #14
0
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 );
}
Beispiel #15
0
void CondVar::Wait(Mutex& externalMutex)
{
#ifdef WIN32
	SignalObjectAndWait(externalMutex.mutex,condVarEvent,INFINITE,FALSE);
	externalMutex.Lock();
#else
	pthread_cond_wait(&condVar,&externalMutex.mutex);
#endif
}
Beispiel #16
0
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;
}
Beispiel #17
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;
	}
}
Beispiel #18
0
	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
    }
Beispiel #20
0
	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;
	}
Beispiel #21
0
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);
  }
}
Beispiel #22
0
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;
}
Beispiel #24
0
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;
}
Beispiel #25
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;
}
Beispiel #26
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
	}
Beispiel #27
0
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;
}
Beispiel #28
0
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;
}
Beispiel #29
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;
}
Beispiel #30
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;
}