1 /* MultiLocker.h */ 2 /* 3 Copyright 2005-2006, Haiku. 4 Distributed under the terms of the MIT license. 5 6 Copyright 1999, Be Incorporated. All Rights Reserved. 7 This file may be used under the terms of the Be Sample Code License. 8 */ 9 10 /** multiple-reader single-writer locking class */ 11 12 // IMPORTANT: 13 // * nested read locks are not supported 14 // * a reader becomming the write is not supported 15 // * nested write locks are supported 16 // * a writer can do read locks, even nested ones 17 // * in case of problems, #define DEBUG 1 in the .cpp 18 19 #ifndef MULTI_LOCKER_H 20 #define MULTI_LOCKER_H 21 22 //#define TIMING 1 23 24 #include <OS.h> 25 26 const int32 LARGE_NUMBER = 100000; 27 28 class MultiLocker { 29 public: 30 MultiLocker(const char* semaphoreBaseName); 31 virtual ~MultiLocker(); 32 33 status_t InitCheck(); 34 35 //locking for reading or writing 36 bool ReadLock(); 37 bool WriteLock(); 38 39 //unlocking after reading or writing 40 bool ReadUnlock(); 41 bool WriteUnlock(); 42 43 //does the current thread hold a write lock ? 44 bool IsWriteLocked(uint32 *stack_base = NULL, 45 thread_id *thread = NULL); 46 //in DEBUG mode returns whether the lock is held 47 //in non-debug mode returns true 48 bool IsReadLocked(); 49 50 private: 51 //functions for managing the DEBUG reader array 52 void register_thread(); 53 void unregister_thread(); 54 55 status_t fInit; 56 //readers adjust count and block on fReadSem when a writer 57 //hold the lock 58 int32 fReadCount; 59 sem_id fReadSem; 60 //writers adjust the count and block on fWriteSem 61 //when readers hold the lock 62 int32 fWriteCount; 63 sem_id fWriteSem; 64 //writers must acquire fWriterLock when acquiring a write lock 65 int32 fLockCount; 66 sem_id fWriterLock; 67 int32 fWriterNest; 68 69 thread_id fWriterThread; 70 uint32 fWriterStackBase; 71 72 int32 * fDebugArray; 73 int32 fMaxThreads; 74 75 #if TIMING 76 uint32 rl_count; 77 bigtime_t rl_time; 78 uint32 ru_count; 79 bigtime_t ru_time; 80 uint32 wl_count; 81 bigtime_t wl_time; 82 uint32 wu_count; 83 bigtime_t wu_time; 84 uint32 islock_count; 85 bigtime_t islock_time; 86 uint32 reg_count; 87 bigtime_t reg_time; 88 uint32 unreg_count; 89 bigtime_t unreg_time; 90 #endif 91 }; 92 93 class AutoWriteLocker { 94 public: 95 AutoWriteLocker(MultiLocker* lock) 96 : fLock(*lock) 97 { 98 fLock.WriteLock(); 99 } 100 AutoWriteLocker(MultiLocker& lock) 101 : fLock(lock) 102 { 103 fLock.WriteLock(); 104 } 105 ~AutoWriteLocker() 106 { 107 fLock.WriteUnlock(); 108 } 109 private: 110 MultiLocker& fLock; 111 }; 112 113 class AutoReadLocker { 114 public: 115 AutoReadLocker(MultiLocker* lock) 116 : fLock(*lock) 117 { 118 fLock.ReadLock(); 119 } 120 AutoReadLocker(MultiLocker& lock) 121 : fLock(lock) 122 { 123 fLock.ReadLock(); 124 } 125 ~AutoReadLocker() 126 { 127 fLock.ReadUnlock(); 128 } 129 private: 130 MultiLocker& fLock; 131 }; 132 133 134 135 #endif 136