ucommon
|
00001 // Copyright (C) 2006-2014 David Sugar, Tycho Softworks. 00002 // 00003 // This file is part of GNU uCommon C++. 00004 // 00005 // GNU uCommon C++ is free software: you can redistribute it and/or modify 00006 // it under the terms of the GNU Lesser General Public License as published 00007 // by the Free Software Foundation, either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // GNU uCommon C++ is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU Lesser General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public License 00016 // along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>. 00017 00031 // we do this twice because of some bizarre issue in just this file that 00032 // otherwise breaks doxygen and lists all items outside the namespace... 00033 #include <ucommon/platform.h> 00034 00035 #ifndef _UCOMMON_ACCESS_H_ 00036 #define _UCOMMON_ACCESS_H_ 00037 00038 #ifndef _UCOMMON_CPR_H_ 00039 #include <ucommon/cpr.h> 00040 #endif 00041 00042 #ifndef _UCOMMON_PROTOCOLS_H_ 00043 #include <ucommon/protocols.h> 00044 #endif 00045 00046 namespace ucommon { 00047 00053 class __EXPORT UnlockAccess 00054 { 00055 public: 00056 virtual ~UnlockAccess(); 00057 00058 protected: 00059 virtual void _unlock(void) = 0; 00060 }; 00061 00068 class __EXPORT ExclusiveAccess : public UnlockAccess 00069 { 00070 protected: 00071 virtual ~ExclusiveAccess(); 00072 00073 virtual void _lock(void) = 0; 00074 00075 public: 00079 inline void exclusive_lock(void) 00080 {return _lock();} 00081 00085 inline void release_exclusive(void) 00086 {return _unlock();} 00087 }; 00088 00095 class __EXPORT SharedAccess : protected UnlockAccess 00096 { 00097 protected: 00098 virtual ~SharedAccess(); 00099 00100 protected: 00104 virtual void _share(void) = 0; 00105 00106 public: 00113 virtual void share(void); 00114 00122 virtual void exclusive(void); 00123 00124 inline void shared_lock(void) 00125 {return _share();} 00126 00127 inline void release_share(void) 00128 {return _unlock();} 00129 }; 00130 00138 class __EXPORT exclusive_access 00139 { 00140 private: 00141 ExclusiveAccess *lock; 00142 00143 public: 00148 exclusive_access(ExclusiveAccess *object); 00149 00153 ~exclusive_access(); 00154 00159 inline bool operator!() const 00160 {return lock == NULL;} 00161 00166 inline operator bool() const 00167 {return lock != NULL;} 00168 00174 void release(void); 00175 }; 00176 00184 class __EXPORT shared_access 00185 { 00186 private: 00187 SharedAccess *lock; 00188 int state; 00189 bool modify; 00190 00191 public: 00196 shared_access(SharedAccess *object); 00197 00201 ~shared_access(); 00202 00207 inline bool operator!() const 00208 {return lock == NULL;} 00209 00214 inline operator bool() const 00215 {return lock != NULL;} 00216 00222 void release(void); 00223 00227 void exclusive(void); 00228 00232 void share(void); 00233 }; 00234 00239 inline void lock(ExclusiveAccess& object) 00240 {object.exclusive_lock();} 00241 00246 inline void unlock(ExclusiveAccess& object) 00247 {object.release_exclusive();} 00248 00253 inline void access(SharedAccess& object) 00254 {object.shared_lock();} 00255 00260 inline void release(SharedAccess& object) 00261 {object.release_share();} 00262 00267 inline void exclusive(SharedAccess& object) 00268 {object.exclusive();} 00269 00274 inline void share(SharedAccess& object) 00275 {object.share();} 00276 00280 typedef exclusive_access exlock_t; 00281 00285 typedef shared_access shlock_t; 00286 00291 inline void release(exlock_t &reference) 00292 {reference.release();} 00293 00298 inline void release(shlock_t &reference) 00299 {reference.release();} 00300 00301 // Special macros to allow member functions of an object with a protocol 00302 // to create self locking states while the member functions are called by 00303 // placing an exclusive_lock or shared_lock smart object on their stack 00304 // frame to reference their self. 00305 00306 #define exclusive_object() exlock_t __autolock__ = this 00307 #define protected_object() shlock_t __autolock__ = this 00308 #define exclusive_locking(x) exlock_t __autolock__ = &x 00309 #define protected_locking(x) shlock_t __autolock__ = &x 00310 00311 } // namespace ucommon 00312 00313 #endif