Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

ReadersWritersLock.H

Go to the documentation of this file.
00001 // Copyright (C) 2001, Compaq Computer Corporation
00002 // 
00003 // This file is part of Vesta.
00004 // 
00005 // Vesta is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 // 
00010 // Vesta is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 // 
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with Vesta; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 
00019 //
00020 // ReadersWritersLock.H
00021 //
00022 // Readers/writers locks
00023 //
00024 #ifndef _RDWRLOCK
00025 #define _RDWRLOCK 1
00026 
00027 #include <pthread.h>
00028 #include "Basics.H"
00029 
00030 #ifdef PTHREAD_RWLOCK_INITIALIZER
00031 // #define USE_PTHREAD_RWLOCK
00032 #endif
00033 
00034 #ifndef USE_PTHREAD_RWLOCK
00035 struct RWLock_Queue_Item;
00036 #endif
00037 
00038 // If we're building an executable without assertions, we might as
00039 // well strip out the acquire/enqueue time.
00040 #if defined(NDEBUG)
00041 #define NO_ACQUIRE_DEBUG_DATA
00042 #endif
00043 
00044 // Simple readers/writers locks.  There can be either many readers,
00045 // one writer, or neither, but not both at once.
00046 
00047 // If favorWriters is false, a new reader is granted the lock whenever
00048 // possible (that is, when the lock is not held, or when other readers
00049 // hold it).  If favorWriters is true, a new reader is not granted the
00050 // lock if one or more writers are waiting to acquire it.
00051 
00052 // Special features for repository: (1) mutex is static, (2) fields
00053 // are public and methods are virtual to allow subclasses to add or
00054 // override methods.
00055 
00056 class ReadersWritersLock {
00057   private:
00058 #ifdef USE_PTHREAD_RWLOCK
00059   pthread_rwlock_t rwlock;
00060 
00061   // Note: this member variable is only modified by a thread holding a
00062   // write lock.
00063   bool write_locked;
00064   
00065   // Try to ensure that the readers/writers lock doesn't chare a cache
00066   // line with anything else.
00067   char pad[64];
00068 
00069 #else
00070     Basics::mutex mu;
00071     // Invariant: either readers == writers == 0, or
00072     //                   readers > 0 && writers == 0, or
00073     //                   readers == 0 && writers = 1
00074     int readers;
00075     int writers;
00076 
00077     RWLock_Queue_Item *q_head, *q_tail;
00078 
00079 #if !defined(NO_ACQUIRE_DEBUG_DATA)
00080     // Debug info: acquire_time and acquire_thread are set when it is
00081     // first locked for reading or writing.  (When there are multiple
00082     // readers, only the first thread sets these.)  This is sometimes
00083     // useful for post-motrem debugging.
00084     time_t acquire_time;
00085     pthread_t acquire_thread;
00086 #endif
00087   
00088 #endif
00089   public:  // normal public methods
00090     ReadersWritersLock(bool favorWriters) throw();
00091     ~ReadersWritersLock() throw();
00092     void acquireRead() throw();
00093     void releaseRead() throw();  // assert(readers > 0);
00094     void acquireWrite() throw();
00095     void releaseWrite() throw(); // assert(writers == 1);
00096 
00097   // virtual void downgradeWriteToRead() throw(); // assert(writers == 1);
00098 
00099     // If lock can be acquired immediately, do so and return true.
00100     // If there is a conflict, return false.
00101     bool tryRead() throw();
00102     bool tryWrite() throw();
00103 
00104     // Assert (readers > 0) xor (writers == 1);
00105     // If writers == 1, releaseWrite and return true.
00106     // If readers > 0, releaseRead and return false.
00107     bool release() throw();
00108 
00109     // Assert (readers > 0) xor (writers == 1);
00110     // If writers == 1, downgradeWriteToRead and return true.
00111     // If readers > 0, return false.
00112     // virtual bool downgrade() throw();
00113 };
00114 #endif //_RDWRLOCK

Generated on Mon May 8 00:48:46 2006 for Vesta by  doxygen 1.4.2