00001 /* 00002 wefts_rwmutex.h 00003 Read/write Non Reentrant Mutex object header file. 00004 00005 $Id: wefts_rwmutex.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 #ifndef WT_RWMUTEX_H 00022 #define WT_RWMUTEX_H 00023 00024 #ifdef __extern_c 00025 extern "C" { 00026 #endif 00027 00028 #include <pthread.h> 00029 00030 #ifdef __extern_c 00031 } 00032 #endif 00033 00034 #ifndef NO_ASSERTION 00035 #include <cassert> 00036 #endif 00037 00038 namespace Wefts { 00039 00064 class RWMutex 00065 { 00066 protected: 00067 pthread_mutex_t m_mutex; 00068 pthread_cond_t m_cond; 00069 volatile int m_lockCount; 00070 volatile int m_promCount; 00071 00072 public: 00074 RWMutex() { 00075 pthread_mutex_init( &m_mutex, NULL ); 00076 pthread_cond_init( &m_cond, NULL ); 00077 m_promCount = m_lockCount = 0; 00078 } 00079 00083 ~RWMutex() { 00084 pthread_cond_destroy( &m_cond ); 00085 pthread_mutex_destroy( &m_mutex ); 00086 } 00087 00093 virtual inline void lockRead() 00094 { 00095 pthread_mutex_lock( &m_mutex ); 00096 while( m_lockCount < 0 ) { 00097 pthread_cond_wait( &m_cond, &m_mutex ); 00098 } 00099 m_lockCount++; 00100 pthread_mutex_unlock( &m_mutex ); 00101 } 00102 00109 virtual inline void lockWrite() 00110 { 00111 pthread_mutex_lock( &m_mutex ); 00112 while( m_lockCount != 0 ) { 00113 pthread_cond_wait( &m_cond, &m_mutex ); 00114 } 00115 m_lockCount = -1; 00116 pthread_mutex_unlock( &m_mutex ); 00117 } 00118 00140 virtual inline void promote() 00141 { 00142 pthread_mutex_lock( &m_mutex ); 00143 #ifndef NO_ASSERTIONS 00144 assert( m_lockCount > 0 ); 00145 #endif 00146 m_promCount++; 00147 while( m_lockCount != m_promCount ) { // count if only this thread itself is left as reading. 00148 pthread_cond_wait( &m_cond, &m_mutex ); 00149 } 00150 m_lockCount = -1; 00151 m_promCount --; 00152 pthread_mutex_unlock( &m_mutex ); 00153 } 00154 00160 virtual inline void unlock() 00161 { 00162 pthread_mutex_lock( &m_mutex ); 00163 m_lockCount = m_lockCount > m_promCount ? m_lockCount-1: m_promCount; 00164 pthread_cond_broadcast( &m_cond ); 00165 pthread_mutex_unlock( &m_mutex ); 00166 } 00167 }; 00168 00169 } 00170 00171 #endif 00172 /* end of wefts_rwmutex.h */