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

📄 wymutex.cpp

📁 一个不错
💻 CPP
字号:
/* Copyright is licensed under GNU LGPL.                 by I.J.Wang 2003*/#define WYLIB_SOURCE#include "wymutex.h"#include <exception>// [Internal] Wy__MutexAttr defines a class for use by WyMutex(constructor)//            execlusively.//class Wy__MutexAttr {  public:    Wy__MutexAttr(WyMutex::MutexType k) WY__TSPC();    ~Wy__MutexAttr() WY__TSPC() { ::pthread_mutexattr_destroy(&_attr); };    const ::pthread_mutexattr_t* attr(void) const WY__TSPC() { return &_attr; };  private:    ::pthread_mutexattr_t _attr;    Wy__MutexAttr();  // not to use};// [Internal] Class is only used to declare const static object//Wy__MutexAttr::Wy__MutexAttr(WyMutex::MutexType k) WY__TSPC()try { int v=::pthread_mutexattr_init(&_attr); if(v!=0) {   WY_TERMINATE(""); // man. always return 0 } switch(k) {   case WyMutex::Fast:        if((v=::pthread_mutexattr_settype(&_attr,PTHREAD_MUTEX_FAST_NP))!=0) {          ::pthread_mutexattr_destroy(&_attr);          WY_TERMINATE(""); // man. says only EINVAL        }        break;   case WyMutex::ErrorCheck:        if((v=::pthread_mutexattr_settype(&_attr,PTHREAD_MUTEX_ERRORCHECK_NP))!=0) {          ::pthread_mutexattr_destroy(&_attr);          WY_TERMINATE(""); // man. says only EINVAL        }        break;   case WyMutex::Recursive:        if((v=::pthread_mutexattr_settype(&_attr,PTHREAD_MUTEX_RECURSIVE_NP))!=0) {          ::pthread_mutexattr_destroy(&_attr);          WY_TERMINATE(""); // man. says only EINVAL        }        break;   default:        ::pthread_mutexattr_destroy(&_attr);        WY_TERMINATE(""); }}catch(...) { WY_TERMINATE("");};//----------------------------------------------------------------------------//// Define the Wy__MutexAttr objects for WyMutex in constructor.//static const Wy__MutexAttr MutexAttr_Fast(WyMutex::Fast);static const Wy__MutexAttr MutexAttr_ErrorCheck(WyMutex::ErrorCheck);static const Wy__MutexAttr MutexAttr_Recursive(WyMutex::Recursive);const char WyMutex::class_name[]="WyMutex";// Construct the mutex//// (POSIX mutex may fail, implement is supposed to be restricted version)//WyMutex::WyMutex(MutexType t) WY__TSPC(Reply)try : _sig(WY_NONE_ID){ int v; switch(t) {   case Fast:         v=::pthread_mutex_init(&_mtx,MutexAttr_Fast.attr());        if(v!=0) {          WY_TERMINATE("");     // man. says always 0        };        break;   case ErrorCheck:        v=::pthread_mutex_init(&_mtx,MutexAttr_ErrorCheck.attr());        if(v!=0) {          WY_TERMINATE("");     // man. says always 0        }        break;   case Recursive:        v=::pthread_mutex_init(&_mtx,MutexAttr_Recursive.attr());        if(v!=0) {          WY_TERMINATE("");     // man. says always 0        }        break;   default:        WY_TERMINATE("");    // MutexType changed, but code not updated. } #ifndef NDEBUG _sig=WYMUTEX_ID; #endif}catch(const WyMutex::Reply&) { throw;}catch(...) { WY_TERMINATE("");};WyMutex::~WyMutex() WY__TSPC(){ #ifndef NDEBUG if(_sig!=WYMUTEX_ID) {   WY_TERMINATE(""); } // Note: Further access of the object cause stack unwind or probably SIGSEGV //       signal // _sig=WY_NONE_ID; #endif for(int i=0; i<30000; ++i) {  // better have a long limit   const int v=::pthread_mutex_destroy(&_mtx);   if(v==0) {     return;      // succeed   }   //   // man. indicates may fail of EBUSY   //   if(v==EBUSY) {     Wy__Base::yield(); // yield should be ok     continue;   }   break; } WY_TERMINATE("");};WyRet WyMutex::lock(void) WY__TSPC(){ #ifndef NDEBUG if(_sig!=WYMUTEX_ID) {   WY_TERMINATE(""); } #endif const int v=::pthread_mutex_lock(&_mtx); if(v!=0) {   WY_RETURN( WyRet(WyReply(v)) ); } return(Ok);};WyRet WyMutex::trylock(void) WY__TSPC(){ #ifndef NDEBUG if(_sig!=WYMUTEX_ID) {   WY_TERMINATE(""); } #endif const int v=::pthread_mutex_trylock(&_mtx); if(v!=0) {   WY_RETURN( WyRet(WyReply(v)) ); } return(Ok);};WyRet WyMutex::unlock(void) WY__TSPC(){ #ifndef NDEBUG if(_sig!=WYMUTEX_ID) {   WY_TERMINATE(""); } #endif // On my Linux platform: //   1. unlock ErrorCheck kind of WyMutex in unlocked state gets EPERM //   2. unlock Fast kind of WyMutex in unlocked state gets 0 //  const int v=::pthread_mutex_unlock(&_mtx); if(v!=0) {   WY_RETURN( WyRet(WyReply(v)) ); } return(Ok);};void WyMutex::lock(WyMutex &mtx) WY__TSPC(Reply){ #ifndef NDEBUG if(mtx._sig!=WYMUTEX_ID) {   WY_TERMINATE(""); } #endif const int v=::pthread_mutex_lock(&mtx._mtx); if(v!=0) {   WY_THROW( Reply(WyReply(v)) ); }};void WyMutex::trylock(WyMutex &mtx) WY__TSPC(Reply){ #ifndef NDEBUG if(mtx._sig!=WYMUTEX_ID) {   WY_TERMINATE(""); } #endif const int v=::pthread_mutex_trylock(&mtx._mtx); if(v!=0) {   WY_THROW( Reply(WyReply(v)) ); }};void WyMutex::unlock(WyMutex &mtx) WY__TSPC(Reply){ #ifndef NDEBUG if(mtx._sig!=WYMUTEX_ID) {   WY_TERMINATE(""); } #endif const int v=::pthread_mutex_unlock(&mtx._mtx); if(v!=0) {   WY_THROW( Reply(WyReply(v)) ); }};::pthread_mutex_t* WyMutex::wy_mutex_ptr(void) WY__TSPC(){ return &_mtx;};//------------------------------------------------const char WyLock::class_name[]="WyLock";WyLock::WyLock(WyMutex &mtx) WY__TSPC(Reply) :_pmtx(NULL){ WyRet r( mtx.lock() ); if(r!=Ok) {   WY_THROW( Reply(r) ); } _pmtx=&mtx;};WyLock::~WyLock() WY__TSPC(){#ifndef NDEBUG if(_pmtx==NULL) {   WY_TERMINATE(""); }#endif const WyRet r(_pmtx->unlock()); if(r!=Ok) {   // none of the manpage listed EPERM/EINVAL should occur   WY_TERMINATE(""); } _pmtx=NULL; };WyRet WyLock::xlock(WyMutex& mtx){#ifndef NDEBUG if(_pmtx==NULL) {   WY_THROW( WyRet(Wym_EFAULT) ); }#endif WyRet r( mtx.lock() ); if(r!=Ok) {   WY_RETURN(r); } if((r=_pmtx->unlock())!=Ok) {   // manual listed errno's EINVAL/EPERM indicate 'internal' error   mtx.unlock();   WY_THROW(r); } _pmtx=&mtx; return(Ok);};

⌨️ 快捷键说明

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