Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   Related Pages  

wefts_rrwmutex.h

Go to the documentation of this file.
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 */

Generated on Tue Aug 5 18:09:00 2003 for Wefts by doxygen1.2.18