00001 /* 00002 * Copyright (c) 2005 Palmsource, Inc. 00003 * 00004 * This software is licensed as described in the file LICENSE, which 00005 * you should have received as part of this distribution. The terms 00006 * are also available at http://www.openbinder.org/license.html. 00007 * 00008 * This software consists of voluntary contributions made by many 00009 * individuals. For the exact contribution history, see the revision 00010 * history and logs, available at http://www.openbinder.org 00011 */ 00012 00013 #ifndef _SUPPORT_LOCKER_H 00014 #define _SUPPORT_LOCKER_H 00015 00021 #include <SysThread.h> 00022 #include <support/SupportDefs.h> 00023 00024 #if TARGET_HOST != TARGET_HOST_WIN32 00025 #include <pthread.h> 00026 #endif 00027 00028 #if _SUPPORTS_NAMESPACE 00029 namespace palmos { 00030 namespace support { 00031 #endif 00032 00037 class SConditionVariable; 00038 00039 /*-------------------------------------------------------------*/ 00040 00042 class SLocker 00043 { 00044 public: 00045 SLocker(); 00046 SLocker(const char* name); 00047 ~SLocker(); 00048 00049 lock_status_t Lock(); 00050 void LockQuick(); 00051 void Yield(); 00052 void Unlock(); 00053 bool IsLocked() const; 00054 00055 class Autolock 00056 { 00057 public: 00058 inline Autolock(SLocker& lock); 00059 inline ~Autolock(); 00060 inline void Unlock(); 00061 private: 00062 SLocker* m_lock; 00063 }; 00064 00065 private: 00066 friend class SConditionVariable; 00067 00068 // For use by SConditionVariable. 00069 void RestoreOwnership(); 00070 volatile int32_t* RemoveOwnership(); 00071 00072 // Blocker can't be copied 00073 SLocker(const SLocker&); 00074 SLocker& operator = (const SLocker&); 00075 00076 volatile int32_t m_lockValue; 00077 }; 00078 00079 /*-------------------------------------------------------------*/ 00080 /*----- SNestedLocker class -----------------------------------*/ 00081 00083 00089 class SNestedLocker 00090 { 00091 public: 00092 SNestedLocker(); 00093 SNestedLocker(const char* name); 00094 ~SNestedLocker(); 00095 00096 lock_status_t Lock(); 00097 void LockQuick(); 00098 void Yield(); 00099 void Unlock(); 00100 00105 int32_t NestingLevel() const; 00106 00107 class Autolock 00108 { 00109 public: 00110 inline Autolock(SNestedLocker& lock); 00111 inline ~Autolock(); 00112 inline void Unlock(); 00113 private: 00114 SNestedLocker* m_lock; 00115 }; 00116 00117 private: 00118 // SNestedLocker can't be copied 00119 SNestedLocker(const SNestedLocker&); 00120 SNestedLocker& operator = (const SNestedLocker&); 00121 00122 static void _UnlockFunc(SNestedLocker* l); 00123 00124 volatile int32_t m_lockValue; 00125 int32_t m_owner; 00126 int32_t m_ownerCount; 00127 }; 00128 00130 class SReadWriteLocker 00131 { 00132 public: 00133 SReadWriteLocker(); 00134 ~SReadWriteLocker(); 00135 00136 lock_status_t ReadLock(); 00137 void ReadLockQuick(); 00138 void ReadUnlock(); 00139 00140 lock_status_t WriteLock(); 00141 void WriteLockQuick(); 00142 void WriteUnlock(); 00143 00144 private: 00145 // SReadWriteLocker can't be copied 00146 SReadWriteLocker(const SReadWriteLocker&); 00147 SReadWriteLocker& operator = (const SReadWriteLocker&); 00148 00149 #if TARGET_HOST == TARGET_HOST_WIN32 00150 SysHandle m_sem; 00151 #else 00152 pthread_rwlock_t m_lock; 00153 #endif 00154 }; 00155 00158 /*-------------------------------------------------------------*/ 00159 /*-------------------------------------------------------------*/ 00160 00161 inline SLocker::Autolock::Autolock(SLocker& lock) 00162 : m_lock(&lock) 00163 { 00164 lock.LockQuick(); 00165 } 00166 00167 inline SLocker::Autolock::~Autolock() 00168 { 00169 if (m_lock) m_lock->Unlock(); 00170 } 00171 00172 inline void SLocker::Autolock::Unlock() 00173 { 00174 if (m_lock) m_lock->Unlock(); 00175 m_lock = NULL; 00176 } 00177 00178 inline SNestedLocker::Autolock::Autolock(SNestedLocker& lock) 00179 : m_lock(&lock) 00180 { 00181 lock.LockQuick(); 00182 } 00183 00184 inline SNestedLocker::Autolock::~Autolock() 00185 { 00186 if (m_lock) m_lock->Unlock(); 00187 } 00188 00189 inline void SNestedLocker::Autolock::Unlock() 00190 { 00191 if (m_lock) m_lock->Unlock(); 00192 m_lock = NULL; 00193 } 00194 00195 #if _SUPPORTS_NAMESPACE 00196 } } // namespace palmos::support 00197 #endif 00198 00199 #endif /* _SUPPORT_LOCKER_H */