Locker.h

Go to the documentation of this file.
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 */