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