00001 // Stefan Gustafsson (sg@nospam.se) RW Lock 00002 // http://groups.google.com/groups?hl=en&lr=&selm=%23l3RF6kO%24GA.267%40cppssbbsa04&rnum=24 00003 00004 #ifndef __SG_RWLock_H_Includded__ 00005 #define __SG_RWLock_H_Includded__ 00006 00007 #include "atomic_util.h" 00008 00009 class SG_RWLock 00010 { 00011 public: 00012 static const char *name() { return "SG_Lock"; } 00013 SG_RWLock() 00014 { 00015 readers = writers = 0; 00016 } 00017 void enter_read() 00018 { 00019 atomic_inc(&readers); 00020 00021 // Wait until all writers have left 00022 while(writers > 0) thread_yield(); 00023 } 00024 void leave_read() 00025 { 00026 atomic_dec(&readers); 00027 } 00028 void enter_write() 00029 { 00030 // Use a critsec for mutual exclusion between writers 00031 l.lock(); 00032 // We must now wait until all readers have left the lock 00033 atomic_inc(&writers); 00034 // -BUG writers++; // Assume there are no readers 00035 while (readers > 0) 00036 { 00037 // Readers in the lock 00038 // Decrement writers again to avoid deadlocking with readers that 00039 // are interrupted immediately after incrementing readers 00040 atomic_dec(&writers); 00041 // - BUG writers--; 00042 thread_yield(); 00043 atomic_inc(&writers); 00044 // --BUG writers++; // Try again 00045 } 00046 } 00047 void leave_write() 00048 { 00049 atomic_dec(&writers); 00050 l.unlock(); 00051 } 00052 private: 00053 volatile int readers; // The number of readers in the lock 00054 volatile int writers; // The number of writers in the lock 00055 SystemLock l; 00056 }; 00057 00058 #endif // __SG_RWLock_H_Includded__