⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tlibthrd.cxx

📁 安装 H323需要的pwlib库
💻 CXX
📖 第 1 页 / 共 4 页
字号:
}///////////////////////////////////////////////////////////////////////////////PSemaphore::PSemaphore(PXClass pxc){  pxClass = pxc;  mutex   = MutexInitialiser;  condVar = CondInitialiser;  // these should never be used, as this constructor is  // only used for PMutex and PSyncPoint and they have their  // own copy constructors  initialVar = maxCountVar = 0;}PSemaphore::PSemaphore(unsigned initial, unsigned maxCount){  pxClass = PXSemaphore;  mutex   = MutexInitialiser;  condVar = CondInitialiser;  initialVar  = initial;  maxCountVar = maxCount;#ifdef P_HAS_SEMAPHORES  PAssertPTHREAD(sem_init, (&semId, 0, initial));#else  PAssert(maxCount > 0, "Invalid semaphore maximum.");  if (initial > maxCount)    initial = maxCount;  currentCount = initial;  maximumCount = maxCount;  queuedLocks  = 0;#endif}PSemaphore::PSemaphore(const PSemaphore & sem){  pxClass = sem.GetSemClass();  mutex   = MutexInitialiser;  condVar = CondInitialiser;  initialVar  = sem.GetInitial();  maxCountVar = sem.GetMaxCount();#ifdef P_HAS_SEMAPHORES  PAssertPTHREAD(sem_init, (&semId, 0, initialVar));#else  PAssert(maxCountVar > 0, "Invalid semaphore maximum.");  if (initialVar > maxCountVar)    initialVar = maxCountVar;  currentCount = initialVar;  maximumCount = maxCountVar;  queuedLocks  = 0;#endif}PSemaphore::~PSemaphore(){  pthread_cond_destroy(&condVar);#ifdef P_NETBSD  // If the mutex was not locked, the unlock will fail */  pthread_mutex_trylock(&mutex);#endif  pthread_mutex_unlock(&mutex);  pthread_mutex_destroy(&mutex);  if (pxClass == PXSemaphore) {#ifdef P_HAS_SEMAPHORES    PAssertPTHREAD(sem_destroy, (&semId));#else    PAssert(queuedLocks == 0, "Semaphore destroyed with queued locks");#endif  }}void PSemaphore::Wait(){#ifdef P_HAS_SEMAPHORES  PAssertPTHREAD(sem_wait, (&semId));#else  PAssertPTHREAD(pthread_mutex_lock, (&mutex));  queuedLocks++;  PThread::Current()->PXSetWaitingSemaphore(this);  while (currentCount == 0) {    int err = pthread_cond_wait(&condVar, &mutex);    PAssert(err == 0 || err == EINTR, psprintf("wait error = %i", err));  }  PThread::Current()->PXSetWaitingSemaphore(NULL);  queuedLocks--;  currentCount--;  PAssertPTHREAD(pthread_mutex_unlock, (&mutex));#endif}BOOL PSemaphore::Wait(const PTimeInterval & waitTime){  if (waitTime == PMaxTimeInterval) {    Wait();    return TRUE;  }  // create absolute finish time   PTime finishTime;  finishTime += waitTime;#ifdef P_HAS_SEMAPHORES#ifdef P_HAS_SEMAPHORES_XPG6  // use proper timed spinlocks if supported.  // http://www.opengroup.org/onlinepubs/007904975/functions/sem_timedwait.html  struct timespec absTime;  absTime.tv_sec  = finishTime.GetTimeInSeconds();  absTime.tv_nsec = finishTime.GetMicrosecond() * 1000;  if (sem_timedwait(&semId, &absTime) == 0) {    return TRUE;  }  else {    return FALSE;  }#else  // loop until timeout, or semaphore becomes available  // don't use a PTimer, as this causes the housekeeping  // thread to get very busy  do {    if (sem_trywait(&semId) == 0)      return TRUE;#if defined(P_LINUX)  // sched_yield in a tight loop is bad karma  // for the linux scheduler: http://www.ussg.iu.edu/hypermail/linux/kernel/0312.2/1127.html    PThread::Current()->Sleep(10);#else    PThread::Yield();#endif  } while (PTime() < finishTime);  return FALSE;#endif#else  struct timespec absTime;  absTime.tv_sec  = finishTime.GetTimeInSeconds();  absTime.tv_nsec = finishTime.GetMicrosecond() * 1000;  PAssertPTHREAD(pthread_mutex_lock, (&mutex));  PThread * thread = PThread::Current();  thread->PXSetWaitingSemaphore(this);  queuedLocks++;  BOOL ok = TRUE;  while (currentCount == 0) {    int err = pthread_cond_timedwait(&condVar, &mutex, &absTime);    if (err == ETIMEDOUT) {      ok = FALSE;      break;    }    else      PAssert(err == 0 || err == EINTR, psprintf("timed wait error = %i", err));  }  thread->PXSetWaitingSemaphore(NULL);  queuedLocks--;  if (ok)    currentCount--;  PAssertPTHREAD(pthread_mutex_unlock, ((pthread_mutex_t *)&mutex));  return ok;#endif}void PSemaphore::Signal(){#ifdef P_HAS_SEMAPHORES  PAssertPTHREAD(sem_post, (&semId));#else  PAssertPTHREAD(pthread_mutex_lock, (&mutex));  if (currentCount < maximumCount)    currentCount++;  if (queuedLocks > 0)     PAssertPTHREAD(pthread_cond_signal, (&condVar));  PAssertPTHREAD(pthread_mutex_unlock, (&mutex));#endif}BOOL PSemaphore::WillBlock() const{#ifdef P_HAS_SEMAPHORES  if (sem_trywait((sem_t *)&semId) != 0) {    PAssertOS(errno == EAGAIN || errno == EINTR);    return TRUE;  }  PAssertPTHREAD(sem_post, ((sem_t *)&semId));  return FALSE;#else  return currentCount == 0;#endif}#if defined(P_QNX) && (P_HAS_RECURSIVE_MUTEX == 1)#define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE#endifPMutex::PMutex()  : PSemaphore(PXMutex){#if P_HAS_RECURSIVE_MUTEX  pthread_mutexattr_t attr;  pthread_mutexattr_init(&attr);  pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);  pthread_mutex_init(&mutex, &attr);#else  ownerThreadId = (pthread_t)-1;#endif}PMutex::PMutex(const PMutex & /*mut*/)  : PSemaphore(PXMutex){#if P_HAS_RECURSIVE_MUTEX  pthread_mutexattr_t attr;  pthread_mutexattr_init(&attr);  pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);  pthread_mutex_init(&mutex, &attr);#else  ownerThreadId = (pthread_t)-1;#endif}void PMutex::Wait(){#if P_HAS_RECURSIVE_MUTEX == 0  pthread_t currentThreadId = pthread_self();  // if the mutex is already acquired by this thread,  // then just increment the lock count  if (pthread_equal(ownerThreadId, currentThreadId)) {    // Note this does not need a lock as it can only be touched by the thread    // which already has the mutex locked.    ++lockCount;    return;  }#endif  // acquire the lock for real  PAssertPTHREAD(pthread_mutex_lock, (&mutex));#if P_HAS_RECURSIVE_MUTEX == 0  PAssert((ownerThreadId == (pthread_t)-1) && (lockCount.IsZero()),          "PMutex acquired whilst locked by another thread");  // Note this is protected by the mutex itself only the thread with  // the lock can alter it.  ownerThreadId = currentThreadId;#endif}BOOL PMutex::Wait(const PTimeInterval & waitTime){  // if waiting indefinitely, then do so  if (waitTime == PMaxTimeInterval) {    Wait();    return TRUE;  }#if P_HAS_RECURSIVE_MUTEX == 0  // get the current thread ID  pthread_t currentThreadId = pthread_self();  // if we already have the mutex, return immediately  if (pthread_equal(ownerThreadId, currentThreadId)) {    // Note this does not need a lock as it can only be touched by the thread    // which already has the mutex locked.    ++lockCount;    return TRUE;  }#endif  // create absolute finish time  PTime finishTime;  finishTime += waitTime;#if P_PTHREADS_XPG6    struct timespec absTime;  absTime.tv_sec  = finishTime.GetTimeInSeconds();  absTime.tv_nsec = finishTime.GetMicrosecond() * 1000;#if P_HAS_RECURSIVE_MUTEX  return pthread_mutex_timedlock(&mutex, &absTime) == 0;#else  if (pthread_mutex_timedlock(&mutex, &absTime) != 0)    return FALSE;  PAssert((ownerThreadId == (pthread_t)-1) && (lockCount.IsZero()),          "PMutex acquired whilst locked by another thread");  // Note this is protected by the mutex itself only the thread with  // the lock can alter it.  ownerThreadId = currentThreadId;  return TRUE;#endif#else // P_PTHREADS_XPG6  do {    if (pthread_mutex_trylock(&mutex) == 0) {#if P_HAS_RECURSIVE_MUTEX == 0      PAssert((ownerThreadId == (pthread_t)-1) && (lockCount.IsZero()),              "PMutex acquired whilst locked by another thread");      // Note this is protected by the mutex itself only the thread with      // the lock can alter it.      ownerThreadId = currentThreadId;#endif // P_HAS_RECURSIVE_MUTEX      return TRUE;    }    PThread::Current()->Sleep(10); // sleep for 10ms  } while (PTime() < finishTime);  return FALSE;#endif // P_PTHREADS_XPG6}void PMutex::Signal(){#if P_HAS_RECURSIVE_MUTEX == 0  if (!pthread_equal(ownerThreadId, pthread_self())) {    PAssertAlways("PMutex signal failed - no matching wait or signal by wrong thread");    return;  }  // if lock was recursively acquired, then decrement the counter  // Note this does not need a separate lock as it can only be touched by the thread  // which already has the mutex locked.  if (!lockCount.IsZero()) {    --lockCount;    return;  }  // otherwise mark mutex as available  ownerThreadId = (pthread_t)-1;#endif  PAssertPTHREAD(pthread_mutex_unlock, (&mutex));}BOOL PMutex::WillBlock() const{#if P_HAS_RECURSIVE_MUTEX == 0  pthread_t currentThreadId = pthread_self();  if (currentThreadId == ownerThreadId)    return FALSE;#endif  pthread_mutex_t * mp = (pthread_mutex_t*)&mutex;  if (pthread_mutex_trylock(mp) != 0)    return TRUE;  PAssertPTHREAD(pthread_mutex_unlock, (mp));  return FALSE;}PSyncPoint::PSyncPoint()  : PSemaphore(PXSyncPoint){  signalCount = 0;}PSyncPoint::PSyncPoint(const PSyncPoint &)  : PSemaphore(PXSyncPoint){  signalCount = 0;}void PSyncPoint::Wait(){  PAssertPTHREAD(pthread_mutex_lock, (&mutex));  while (signalCount == 0)    pthread_cond_wait(&condVar, &mutex);  signalCount--;  PAssertPTHREAD(pthread_mutex_unlock, (&mutex));}BOOL PSyncPoint::Wait(const PTimeInterval & waitTime){  PAssertPTHREAD(pthread_mutex_lock, (&mutex));  PTime finishTime;  finishTime += waitTime;  struct timespec absTime;  absTime.tv_sec  = finishTime.GetTimeInSeconds();  absTime.tv_nsec = finishTime.GetMicrosecond() * 1000;  int err = 0;  while (signalCount == 0) {    err = pthread_cond_timedwait(&condVar, &mutex, &absTime);    if (err == 0 || err == ETIMEDOUT)      break;    PAssertOS(err == EINTR && errno == EINTR);  }  if (err == 0)    signalCount--;  PAssertPTHREAD(pthread_mutex_unlock, (&mutex));  return err == 0;}void PSyncPoint::Signal(){  PAssertPTHREAD(pthread_mutex_lock, (&mutex));  signalCount++;  PAssertPTHREAD(pthread_cond_signal, (&condVar));  PAssertPTHREAD(pthread_mutex_unlock, (&mutex));}BOOL PSyncPoint::WillBlock() const{  return signalCount == 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -