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

📄 sbtrdmutex.cpp

📁 OSB-PIK-OpenVXI-3.0.0源代码 “中国XML论坛 - 专业的XML技术讨论区--XML在语音技术中的应用”
💻 CPP
字号:
/* SBtrdMutex, classes for managing various types of mutexes */ /****************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.  *  ***********************************************************************/  static const char *rcsid = 0 ? (char *) &rcsid : "$Id: SBtrdMutex.cpp,v 7.3.2.2 2003/10/06 17:57:32 mpanacci Exp $";  // -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8  #define SBTRDUTIL_EXPORTS #include "SBtrdMutex.hpp"             // Header for this class  #include <stdio.h> #include <limits.h>                   // For ULONG_MAX  #include "VXIlog.h"                   // For logging  // -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8  // Destructor SBTRDUTIL_API_CLASS SBtrdMutex::~SBtrdMutex( ) {   if ( _name )     delete [] _name;    if ( _mutex )     VXItrdMutexDestroy (&_mutex); }   // Creation method SBTRDUTIL_API_CLASS VXItrdResult  SBtrdMutex::Create (const wchar_t *name) {   if (( ! name ) || ( ! name[0] ))     return VXItrd_RESULT_INVALID_ARGUMENT;      // Save a copy of the name   size_t len = wcslen (name);   _name = new wchar_t[len];   if ( ! _name )     return VXItrd_RESULT_OUT_OF_MEMORY;      // Create the mutex   return VXItrdMutexCreate (&_mutex); }   // Lock and unlock the mutex. Declared as const so that users can // lock/unlock for read access within const methods.  NOTE: Not // inlined, otherwise users of SBtrdUtil would have to manually link // to SBtrd directly instead of just requiring the former. SBTRDUTIL_API_CLASS VXItrdResult SBtrdMutex::Lock( ) const  {    return VXItrdMutexLock (_mutex); }  SBTRDUTIL_API_CLASS VXItrdResult SBtrdMutex::Unlock( ) const {    return VXItrdMutexUnlock (_mutex); }   // -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8   // CrossThreadMutex creation method SBTRDUTIL_API_CLASS VXItrdResult SBtrdReaderWriterMutex::CrossThreadMutex::Create (const wchar_t *name) {   VXItrdResult rc = SBtrdMutex::Create (name);   if ( rc == VXItrd_RESULT_SUCCESS )     rc = VXItrdTimerCreate (&_timer);   return rc; }   // CrossThreadMutex lock method SBTRDUTIL_API_CLASS VXItrdResult SBtrdReaderWriterMutex::CrossThreadMutex::Lock( ) const {   VXItrdResult rc;   if ( (rc = SBtrdMutex::Lock( )) == VXItrd_RESULT_SUCCESS ) {     while (( _locked ) &&  	   ( (rc = VXItrdTimerSleep (_timer, INT_MAX, NULL)) == 	     VXItrd_RESULT_SUCCESS ))       ; // keep waiting          if ( rc == VXItrd_RESULT_SUCCESS ) {       CrossThreadMutex *pThis = const_cast<CrossThreadMutex *>(this);       pThis->_locked = true;     }          if ( SBtrdMutex::Unlock( ) != VXItrd_RESULT_SUCCESS )       rc = VXItrd_RESULT_SYSTEM_ERROR;   }    return rc; }   // CrossThreadMutex unlock method SBTRDUTIL_API_CLASS VXItrdResult SBtrdReaderWriterMutex::CrossThreadMutex::Unlock( ) const {   if ( ! _locked )     return VXItrd_RESULT_FATAL_ERROR;    CrossThreadMutex *pThis = const_cast<CrossThreadMutex *>(this);   pThis->_locked = false;   return VXItrdTimerWake (_timer); }   // Creation method SBTRDUTIL_API_CLASS VXItrdResult  SBtrdReaderWriterMutex::Create (const wchar_t *name) {   // Need five underlying mutex. We'll use the mutex from our base   // class for the write lock.   VXItrdResult rc;   if (( (rc = SBtrdMutex::Create (name)) != VXItrd_RESULT_SUCCESS ) ||       ( (rc = _readerMutex.Create (name)) != VXItrd_RESULT_SUCCESS ) ||       ( (rc = _writerMutex.Create (name)) != VXItrd_RESULT_SUCCESS ) ||       ( (rc = _readerCountMutex.Create (name)) != VXItrd_RESULT_SUCCESS ) ||       ( (rc = _writerCountMutex.Create (name)) != VXItrd_RESULT_SUCCESS )) {     Error (0, NULL);     return rc;   }    return VXItrd_RESULT_SUCCESS; }   // Obtain write access SBTRDUTIL_API_CLASS VXItrdResult SBtrdReaderWriterMutex::Lock( ) const {   VXItrdResult rc = VXItrd_RESULT_SUCCESS;  #ifdef FAKE_READER_WRITER_MUTEX   rc = SBtrdMutex::Lock( ); #else   Diag (0, L"SBtrdReaderWriterMutex::Lock", L"enter: rwMutex 0x%p", this);    // Get the writer lock, writers have preference   if ( _writerCountMutex.Lock( ) != VXItrd_RESULT_SUCCESS ) {     Error (1, NULL);     return VXItrd_RESULT_SYSTEM_ERROR;   }    if ( _writerCount < ULONG_MAX ) {     SBtrdReaderWriterMutex *pThis = const_cast<SBtrdReaderWriterMutex *>(this);     ++(pThis->_writerCount);     if ( _writerCount == 1 ) {       Diag (0, L"SBtrdReaderWriterMutex::Lock", L"first writer 0x%p", this);       if ( _readerMutex.Lock( ) != VXItrd_RESULT_SUCCESS ) { 	Error (2, NULL); 	rc = VXItrd_RESULT_SYSTEM_ERROR;       }     }   } else {     Error (3, NULL);     rc = VXItrd_RESULT_FATAL_ERROR;   }    if ( _writerCountMutex.Unlock( ) != VXItrd_RESULT_SUCCESS ) {     Error (40, NULL);     rc = VXItrd_RESULT_SYSTEM_ERROR;   } else if (( rc == VXItrd_RESULT_SUCCESS ) && 	     ( _writerMutex.Lock( ) != VXItrd_RESULT_SUCCESS )) {     Error (4, NULL);     rc = VXItrd_RESULT_SYSTEM_ERROR;   }    Diag (0, L"SBtrdReaderWriterMutex::Lock", L"exit: rwMutex 0x%p", this); #endif    return rc; }   // Release write access SBTRDUTIL_API_CLASS VXItrdResult SBtrdReaderWriterMutex::Unlock( ) const {   VXItrdResult rc = VXItrd_RESULT_SUCCESS;  #ifdef FAKE_READER_WRITER_MUTEX   rc = SBtrdMutex::Unlock( ); #else   Diag (0, L"SBtrdReaderWriterMutex::Unlock", L"enter: rwMutex 0x%p", this);    // Release the writer lock, preserve writer preference   if (( _writerMutex.Unlock( ) != VXItrd_RESULT_SUCCESS ) ||       ( _writerCountMutex.Lock( ) != VXItrd_RESULT_SUCCESS )) {     Error (5, NULL);     return VXItrd_RESULT_SYSTEM_ERROR;   }    if ( _writerCount > 0 ) {     SBtrdReaderWriterMutex *pThis = const_cast<SBtrdReaderWriterMutex *>(this);     --(pThis->_writerCount);     if ( _writerCount == 0 ) {       Diag (0, L"SBtrdReaderWriterMutex::Unlock", L"last writer 0x%p", this);       if ( _readerMutex.Unlock( ) != VXItrd_RESULT_SUCCESS ) { 	Error (6, NULL); 	rc = VXItrd_RESULT_SYSTEM_ERROR;       }     }   } else {     Error (7, NULL);     rc = VXItrd_RESULT_FATAL_ERROR;   }      if ( _writerCountMutex.Unlock( ) != VXItrd_RESULT_SUCCESS ) {     Error (8, NULL);     rc = VXItrd_RESULT_SYSTEM_ERROR;   }    Diag (0, L"SBtrdReaderWriterMutex::Unlock", L"exit: rwMutex 0x%p", this); #endif    return rc; }   // Obtain read access. Declared as const so that users can lock/unlock // for read access within const methods. SBTRDUTIL_API_CLASS VXItrdResult  SBtrdReaderWriterMutex::StartRead( ) const {   VXItrdResult rc = VXItrd_RESULT_SUCCESS;  #ifdef FAKE_READER_WRITER_MUTEX   rc = SBtrdMutex::Lock( ); #else   Diag (0, L"SBtrdReaderWriterMutex::StartRead", L"enter: rwMutex 0x%p", this);    // Wait on mutexes, giving writers preference   if (( SBtrdMutex::Lock( ) != VXItrd_RESULT_SUCCESS ) ||       ( _readerMutex.Lock( ) != VXItrd_RESULT_SUCCESS ) ||       ( _readerCountMutex.Lock( ) != VXItrd_RESULT_SUCCESS )) {     Error (9, NULL);     return VXItrd_RESULT_SYSTEM_ERROR;   }      if ( _readerCount < ULONG_MAX ) {     SBtrdReaderWriterMutex *pThis = const_cast<SBtrdReaderWriterMutex *>(this);     ++(pThis->_readerCount);     if ( _readerCount == 1 ) {       Diag (0, L"SBtrdReaderWriterMutex::StartRead",L"first reader 0x%p",this);       if ( _writerMutex.Lock( ) != VXItrd_RESULT_SUCCESS ) { 	Error (10, NULL); 	rc = VXItrd_RESULT_SYSTEM_ERROR;       }     }   } else {     Error (11, NULL);     rc = VXItrd_RESULT_FATAL_ERROR;   }      if (( _readerCountMutex.Unlock( ) != VXItrd_RESULT_SUCCESS ) ||       ( _readerMutex.Unlock( ) != VXItrd_RESULT_SUCCESS ) ||       ( SBtrdMutex::Unlock( ) != VXItrd_RESULT_SUCCESS )) {     Error (12, NULL);     rc = VXItrd_RESULT_SYSTEM_ERROR;   }      Diag (0, L"SBtrdReaderWriterMutex::StartRead", L"exit: rwMutex 0x%p", this); #endif    return rc; }   // Release read access. Declared as const so that users can lock/unlock // for read access within const methods. SBTRDUTIL_API_CLASS VXItrdResult  SBtrdReaderWriterMutex::EndRead( ) const {   VXItrdResult rc = VXItrd_RESULT_SUCCESS;  #ifdef FAKE_READER_WRITER_MUTEX   rc = SBtrdMutex::Unlock( ); #else   Diag (0, L"SBtrdReaderWriterMutex::EndRead", L"enter: rwMutex 0x%p", this);    // Release mutex, preserving writer preference   if ( _readerCountMutex.Lock( ) != VXItrd_RESULT_SUCCESS ) {     Error (13, NULL);     return VXItrd_RESULT_SYSTEM_ERROR;   }    if ( _readerCount > 0 ) {     SBtrdReaderWriterMutex *pThis = const_cast<SBtrdReaderWriterMutex *>(this);     --(pThis->_readerCount);     if ( _readerCount == 0 ) {       Diag (0, L"SBtrdReaderWriterMutex::EndRead", L"last reader 0x%p", this);       if ( _writerMutex.Unlock( ) != VXItrd_RESULT_SUCCESS ) { 	Error (14, NULL); 	rc = VXItrd_RESULT_SYSTEM_ERROR;       }     }   } else {     Error (15, NULL);     rc = VXItrd_RESULT_FATAL_ERROR;   }      if ( _readerCountMutex.Unlock( ) != VXItrd_RESULT_SUCCESS ) {     Error (16, NULL);     rc = VXItrd_RESULT_SYSTEM_ERROR;   }    Diag (0, L"SBtrdReaderWriterMutex::EndRead", L"exit: rwMutex 0x%p", this); #endif    return rc; }   // Error logging SBTRDUTIL_API_CLASS void SBtrdReaderWriterMutex::Error (VXIunsigned errorID, const VXIchar *format, 			       ...) const {   if ( _log ) {     if ( format ) {       va_list arguments;       va_start(arguments, format);       (*_log->VError)(_log, COMPANY_DOMAIN L"SBtrdUtil", errorID, format, 		      arguments);       va_end(arguments);     } else {       (*_log->Error)(_log, COMPANY_DOMAIN L"SBtrdUtil", errorID, NULL);     }   }   }   // Diagnostic logging SBTRDUTIL_API_CLASS void SBtrdReaderWriterMutex::Diag (VXIunsigned tag, const VXIchar *subtag,  			      const VXIchar *format, ...) const {   if ( _log ) {     if ( format ) {       va_list arguments;       va_start(arguments, format);       (*_log->VDiagnostic)(_log, tag + _diagTagBase, subtag, format,  			   arguments);       va_end(arguments);     } else {       (*_log->Diagnostic)(_log, tag + _diagTagBase, subtag, NULL);     } #if 0   } else {     VXIchar temp[1024];     va_list arguments;     va_start(arguments, format);     wcscpy (temp, subtag);     wcscat (temp, L"|");     wcscat (temp, format);     wcscat (temp, L"\n");     vfwprintf(stderr, temp, arguments);     va_end(arguments); #endif   } }   // -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8   // Creation method, the name is simply for logging purposes SBTRDUTIL_API_CLASS VXItrdResult  SBtrdMutexPool::Create (const wchar_t *name, unsigned int size) {   if (( ! name ) || ( ! name[0] ) || ( size == 0 ))     return VXItrd_RESULT_INVALID_ARGUMENT;    // Create the mutex pool   _pool = new SBtrdMutex [size];   if ( ! _pool )     return VXItrd_RESULT_OUT_OF_MEMORY;    // Initialize the mutexes   VXItrdResult rc = VXItrd_RESULT_SUCCESS;   for (unsigned int i = 0; i < size; i++) {     if ( (rc = _pool[i].Create (name)) != VXItrd_RESULT_SUCCESS ) {       delete [] _pool;       return rc;     }   }      _size = size;   return VXItrd_RESULT_SUCCESS; }   // Obtain a mutex out of the pool, the mutex pool continues to own // this mutex so you must not destroy it, and this mutex may be // returned multiple times SBTRDUTIL_API_CLASS SBtrdMutex *SBtrdMutexPool::GetMutex( ) {   if ( _pool == NULL )     return NULL;    // Lock using mutex 0   if ( _pool[0].Lock( ) != VXItrd_RESULT_SUCCESS )     return NULL;    // Retrieve the appropriate mutex and increment the index for   // round-robin allocation   SBtrdMutex *mutex = &_pool[_curIndex];   if ( _curIndex < _size - 1 )     _curIndex++;   else     _curIndex = 0;    // Unlock using mutex 0   if ( _pool[0].Unlock( ) != VXItrd_RESULT_SUCCESS )     return NULL;    return mutex; } // -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8   // Creation method, the name is simply for logging purposes SBTRDUTIL_API_CLASS VXItrdResult  SBtrdReaderWriterMutexPool::Create (const wchar_t *name, unsigned int size) {   if (( ! name ) || ( ! name[0] ) || ( size == 0 ))     return VXItrd_RESULT_INVALID_ARGUMENT;    // Create the allocation mutex   _allocationMutex = new SBtrdMutex;   if ( ! _allocationMutex )     return VXItrd_RESULT_OUT_OF_MEMORY;      // Create the mutex pool   _pool = new SBtrdReaderWriterMutex [size];   if ( ! _pool )     return VXItrd_RESULT_OUT_OF_MEMORY;    // Initialize the mutexes   VXItrdResult rc = VXItrd_RESULT_SUCCESS;   if ( (rc = _allocationMutex->Create (name)) != VXItrd_RESULT_SUCCESS ) {     delete _allocationMutex;     return rc;   }    for (unsigned int i = 0; i < size; i++) {     if ( (rc = _pool[i].Create (name)) != VXItrd_RESULT_SUCCESS ) {       delete [] _pool;       return rc;     }   }      _size = size;   return VXItrd_RESULT_SUCCESS; }   // Obtain a mutex out of the pool, the mutex pool continues to own // this mutex so you must not destroy it, and this mutex may be // returned multiple times SBTRDUTIL_API_CLASS SBtrdReaderWriterMutex * SBtrdReaderWriterMutexPool::GetMutex( ) {   if ( _pool == NULL )     return NULL;    // Lock for exlusive access   if ( _allocationMutex->Lock( ) != VXItrd_RESULT_SUCCESS )     return NULL;    // Retrieve the appropriate mutex and increment the index for   // round-robin allocation   SBtrdReaderWriterMutex *mutex = &_pool[_curIndex];   if ( _curIndex < _size - 1 )     _curIndex++;   else     _curIndex = 0;    // Unlock   if ( _allocationMutex->Unlock( ) != VXItrd_RESULT_SUCCESS )     return NULL;    return mutex; }

⌨️ 快捷键说明

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