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

📄 switrdmonitor.cpp

📁 sloedgy open sip stack source code
💻 CPP
📖 第 1 页 / 共 2 页
字号:

 /****************License************************************************
  *
  * Copyright 2000-2003.  ScanSoft, Inc.    
  *
  * Use of this software is subject to notices and obligations set forth 
  * in the SpeechWorks Public License - Software Version 1.2 which is 
  * included with this software. 
  *
  * ScanSoft is a registered trademark of ScanSoft, Inc., and OpenSpeech, 
  * SpeechWorks and the SpeechWorks logo are registered trademarks or 
  * trademarks of SpeechWorks International, Inc. in the United States 
  * and other countries.
  *
  ***********************************************************************/
 
#include <vxibuildopts.h>
#if P_VXI


 #include "SWIutilInternal.h"
 
 #ifndef _WIN32
 #include <sys/time.h>
 #include <errno.h>
 #define INFINITE (~0)
 #endif
 
 #include "SWItrdMonitor.hpp"
 #include <vxi/VXItrd.h>
 
 #ifdef _WIN32
 #ifndef WIN32_LEAN_AND_MEAN
 #define WIN32_LEAN_AND_MEAN
 #endif
 #include <windows.h>
 #else
 #include <pthread.h>
 #endif
 
 // ---------- Constants ----------
 
 const int SWItrdMonitor::SUCCESS = 0;
 const int SWItrdMonitor::FAILURE = -1;
 const int SWItrdMonitor::NOT_OWNER = 1;
 
 // Static initialization for WIN32
 #ifdef _WIN32
 
 static void *createMutex(bool locked)
 {
   HANDLE *k = new HANDLE;
   *k = CreateMutex(NULL, locked ? TRUE : FALSE, NULL);
   return k;
 }
 
 static void deleteMutex(void *mutex)
 {
   HANDLE *k = (HANDLE *) mutex;
   CloseHandle(*k);
   delete k;
 }
 
 static int lockMutex(void* mutex)
 {
   int rc = SWItrdMonitor::SUCCESS;
   switch (WaitForSingleObject(*(static_cast<HANDLE *>(mutex)), INFINITE))
   {
    case WAIT_FAILED:
      rc = SWItrdMonitor::FAILURE;
      break;
    case WAIT_ABANDONED:
      // should we log this?
      break;
   }
   return rc;
 }
 
 static int unlockMutex(void* mutex)
 {
   return ReleaseMutex(*(static_cast<HANDLE *>(mutex))) ?
     SWItrdMonitor::SUCCESS :
     SWItrdMonitor::FAILURE;
 }
 
 static int waitForEvent(void *mutex,
                         void *event,
                         unsigned long millisecs,
                         bool *expiredF)
 {
   if (::unlockMutex(mutex) != SWItrdMonitor::SUCCESS)
   {
     return SWItrdMonitor::FAILURE;
   }
 
   int rc = SWItrdMonitor::SUCCESS;
 
   DWORD waitrc = WaitForSingleObject(*(static_cast<HANDLE *>(event)),
                                      millisecs);
   switch (waitrc)
   {
    case WAIT_OBJECT_0:
      if (expiredF != NULL) *expiredF = false;
      break;
    case WAIT_TIMEOUT:
      if (expiredF != NULL) *expiredF = true;
      break;
    case WAIT_FAILED:
      rc = SWItrdMonitor::FAILURE;
      break;
    case WAIT_ABANDONED:
      // should we log this?
      break;
   }
   ::lockMutex(mutex);
   return rc;
 }
 
 static int notifyEvent(void *event, bool broadcast)
 {
   SetEvent(*(static_cast<HANDLE *>(event)));
   return SWItrdMonitor::SUCCESS;
 }
 
 #else
 
 static void *createMutex(bool locked)
 {
   pthread_mutex_t *lock = new pthread_mutex_t;
   pthread_mutex_init(lock,NULL);
   if (locked) pthread_mutex_lock(lock);
   return lock;
 }
 
 static void deleteMutex(void *mutex)
 {
   pthread_mutex_t *lock = (pthread_mutex_t *) mutex;
   pthread_mutex_destroy(lock);
   delete lock;
 }
 
 static int lockMutex(void *mutex)
 {
   return pthread_mutex_lock(static_cast<pthread_mutex_t *>(mutex)) == 0 ?
     SWItrdMonitor::SUCCESS :
     SWItrdMonitor::FAILURE;
 }
 
 static int unlockMutex(void *mutex)
 {
   return pthread_mutex_unlock(static_cast<pthread_mutex_t *>(mutex)) == 0 ?
     SWItrdMonitor::SUCCESS :
     SWItrdMonitor::FAILURE;
 }
 
 static int waitForEvent(void *mutex, void *event,
                         unsigned long millisecs,
                         bool *expiredF)
 {
   int rc = SWItrdMonitor::SUCCESS;
 
   if (millisecs == INFINITE)
   {
     if (pthread_cond_wait(static_cast<pthread_cond_t *>(event),
                           static_cast<pthread_mutex_t *>(mutex)) != 0)
       rc = SWItrdMonitor::FAILURE;
   }
   else
   {
     struct timeval now;
     struct timespec timeout;
 
     gettimeofday(&now, NULL);
     timeout.tv_sec = now.tv_sec + millisecs / 1000;
     unsigned long microsecs = now.tv_usec + (millisecs % 1000) * 1000;
     if (microsecs >= 1000000)
     {
       microsecs -= 1000000;
       timeout.tv_sec++;
     }
     timeout.tv_nsec = microsecs * 1000;
 
     rc = pthread_cond_timedwait(static_cast<pthread_cond_t *>(event),
                                 static_cast<pthread_mutex_t *>(mutex),
                                 &timeout);
 
     switch (rc)
     {
      case 0:
        if (expiredF != NULL) *expiredF = false;
        rc = SWItrdMonitor::SUCCESS;
        break;
      case ETIMEDOUT:
        if (expiredF != NULL) *expiredF = true;
        rc = SWItrdMonitor::SUCCESS;
        break;
      default:
        rc = SWItrdMonitor::FAILURE;
     }
   }
   return rc;
 }
 
 static int notifyEvent(void *event, bool broadcast)
 {
   pthread_cond_t *p = static_cast<pthread_cond_t *>(event);
   int rc;
 
   if (broadcast)
     rc = pthread_cond_broadcast(p);
   else
     rc = pthread_cond_signal(p);
 
   if (rc == 0)
     rc = SWItrdMonitor::SUCCESS;
   else
     rc = SWItrdMonitor::FAILURE;
 
   return rc;
 }
 
 #endif
 
 void* SWItrdMonitor::_globalLock = createMutex(false);
 SWItrdMonitor::HandleListItem * volatile SWItrdMonitor::_freeThreadList = NULL;
 SWItrdMonitor::HandleListItem * volatile SWItrdMonitor::_freeMutexList = NULL;
 
 // SWItrdMonitor::SWItrdMonitor
 // Refer to SWItrdMonitor.hpp for doc.
 SWItrdMonitor::SWItrdMonitor(Policy policy):
   _ownerThread((VXIthreadID) -1),_lockCount(0),
   _firstWaitingThread(NULL),_lastWaitingThread(NULL),
   _mutex(NULL),
   _policy(policy)
 {
   if (policy != POOLED)
   {
     _mutex = new HandleListItem;
     // We don't initialize the other fields as we don't really care
     _mutex->_handle = ::createMutex(false);
   }
 }
 
 // SWItrdMonitor::~SWItrdMonitor
 // Refer to SWItrdMonitor.hpp for doc.
 SWItrdMonitor::~SWItrdMonitor()
 {
   ::lockMutex(_globalLock);
 
   // If the list of waiting threads is not NULL, we unlock them and put them
   // back on the free list.  This way, wait() will return with an error rather
   // than block indefinitely.
   if (_firstWaitingThread != NULL)
   {
     notifyAllHandles();
   }
 
   if (_policy == POOLED)
   {
     // release the mutex if we have one, and put it back on the free list.
     if (_mutex != NULL)
     {
       ::unlockMutex(_mutex->_handle);
       _mutex->_next = _freeMutexList;
       _freeMutexList = _mutex;
       _mutex = NULL;
     }
     ::unlockMutex(_globalLock);
   }
   else
   {
     ::unlockMutex(_globalLock);
     ::deleteMutex(_mutex->_handle);
     delete _mutex;
   }
 }
 
 // lock
 // Refer to SWItrdMonitor.hpp for doc.
 int SWItrdMonitor::lock()
 {
   // body
   VXIthreadID threadId = VXItrdThreadGetID();
   if (threadId == _ownerThread)
   {
     _lockCount++;
     return SUCCESS;
   }
 
   int rc = SUCCESS;
   if (_policy == POOLED)
   {
     if (::lockMutex(_globalLock) != SUCCESS)
       return FAILURE;
 
     bool newMutex = false;
 
     if (_mutex == NULL)
     {
       if (_freeMutexList == NULL)
       {
         _mutex = new HandleListItem;
         // We don't initialize the other fields as we don't really care
         _mutex->_handle = ::createMutex(true);
         newMutex = true;
         if (_mutex->_handle == NULL)
         {
           delete _mutex;
           _mutex = NULL;
         }
       }
       else
       {
         // Take a mutex from the free list.  This actually is a stack of mutex
         // as it is.  I don't think it causes a problem anyway.
         _mutex = _freeMutexList;
         _freeMutexList = _freeMutexList->_next;
       }
       _mutex->_count = 1;
     }
     else
     {
       _mutex->_count++;
     }
 
     rc = ::unlockMutex(_globalLock);
     if (rc != SUCCESS || _mutex == NULL)
     {

⌨️ 快捷键说明

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