00001 /* 00002 wefts_rrwmutex.h 00003 Read/write Reentrant/advanced Mutex object header file. 00004 00005 $Id: wefts_rrwmutex.h,v 1.2 2003/08/05 15:40:20 jonnymind Exp $ 00006 --------------------------------------------- 00007 Begin : 2003-08-02 20:58 00008 Author : Giancarlo Niccolai 00009 00010 Last modified because: 00011 00012 */ 00013 00014 /************************************************************************** 00015 * This program is free software; you can redistribute it and/or modify * 00016 * it under the terms of the GNU Library General Public License as * 00017 * published by the Free Software Foundation; either version 2.1 of the * 00018 * License, or (at your option) any later version. * 00019 ***************************************************************************/ 00020 00021 00022 #ifndef WT_RRWMUTEX_H 00023 #define WT_RRWMUTEX_H 00024 00025 #include <wefts_rwmutex.h> 00026 #ifndef NO_ASSERTIONS 00027 #include <cassert> 00028 #endif 00029 00030 namespace Wefts { 00031 00051 class RRWMutex: public RWMutex { 00052 private: 00053 volatile int m_fence; 00054 pthread_t m_owner; 00055 00056 public: 00058 RRWMutex(): RWMutex() { 00059 m_fence = 0; 00060 m_owner = 0; 00061 } 00062 00071 virtual inline void lockRead() 00072 { 00073 pthread_mutex_lock( &m_mutex ); 00074 while( m_fence > 0 || m_lockCount < 0 || m_promCount > 0) { 00075 pthread_cond_wait( &m_cond, &m_mutex ); 00076 } 00077 m_lockCount++; 00078 pthread_mutex_unlock( &m_mutex ); 00079 } 00080 00094 virtual inline void promote( bool fence ) 00095 { 00096 volatile pthread_t thid = pthread_self(); 00097 pthread_mutex_lock( &m_mutex ); 00098 #ifndef NO_ASSERTIONS 00099 assert( m_lockCount > 0 ); 00100 #endif 00101 m_promCount++; 00102 if ( fence ) m_fence ++; 00103 while( m_lockCount != m_promCount ) { // count if only this thread itself is left as reading. 00104 pthread_cond_wait( &m_cond, &m_mutex ); 00105 } 00106 m_lockCount = -1; 00107 m_owner = thid; 00108 // I can release my fence, as reading threads are now blocked by 00109 // the write lock, but I cannot set it to 0: other write lockers 00110 // could have issued a fence before I had this lock. 00111 if (fence) m_fence--; 00112 m_promCount--; 00113 pthread_mutex_unlock( &m_mutex ); 00114 } 00115 00116 virtual void inline promote() { promote( false ); } 00117 00127 virtual inline void lockWrite( bool fence ) 00128 { 00129 volatile pthread_t thid = pthread_self(); 00130 pthread_mutex_lock( &m_mutex ); 00131 if ( fence ) m_fence ++; 00132 while( m_lockCount > 0 || ( m_owner != thid && m_owner != 0)) { 00133 pthread_cond_wait( &m_cond, &m_mutex ); 00134 } 00135 m_lockCount--; 00136 m_owner = thid; 00137 // I can release my fence, as reading threads are now blocked by 00138 // the write lock, but I cannot set it to 0: other write lockers 00139 // could have issued a fence before I had this lock. 00140 if (fence) m_fence--; 00141 pthread_mutex_unlock( &m_mutex ); 00142 } 00143 00147 virtual inline void lockWrite() { lockWrite( false ); } 00148 00155 virtual inline void unlock() 00156 { 00157 pthread_mutex_lock( &m_mutex ); 00158 if ( m_lockCount > 0 ) { 00159 m_lockCount --; 00160 if ( m_lockCount == m_promCount ) 00161 pthread_cond_broadcast( &m_cond ); 00162 } 00163 else { 00164 if ( m_owner == pthread_self() ) { 00165 m_lockCount++; 00166 if ( m_lockCount == 0 ) { 00167 m_owner = 0; 00168 m_lockCount = m_promCount; 00169 pthread_cond_broadcast( &m_cond ); 00170 } 00171 } 00172 } 00173 pthread_mutex_unlock( &m_mutex ); 00174 } 00175 }; 00176 00177 } 00178 00179 #endif 00180 /* end of wefts_rrwmutex.h */