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