ucommon
|
00001 // Copyright (C) 2006-2010 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 00053 #ifndef _UCOMMON_THREAD_H_ 00054 #define _UCOMMON_THREAD_H_ 00055 00056 #ifndef _UCOMMON_CPR_H_ 00057 #include <ucommon/cpr.h> 00058 #endif 00059 00060 #ifndef _UCOMMON_ACCESS_H_ 00061 #include <ucommon/access.h> 00062 #endif 00063 00064 #ifndef _UCOMMON_TIMERS_H_ 00065 #include <ucommon/timers.h> 00066 #endif 00067 00068 #ifndef _UCOMMON_MEMORY_H_ 00069 #include <ucommon/memory.h> 00070 #endif 00071 00072 NAMESPACE_UCOMMON 00073 00074 class SharedPointer; 00075 00086 class __EXPORT Conditional 00087 { 00088 private: 00089 friend class ConditionalAccess; 00090 00091 #if defined(_MSCONDITIONAL_) 00092 CRITICAL_SECTION mutex; 00093 CONDITION_VARIABLE cond; 00094 #elif defined(_MSWINDOWS_) 00095 enum {SIGNAL = 0, BROADCAST = 1}; 00096 HANDLE events[2]; 00097 unsigned waiting; 00098 CRITICAL_SECTION mlock; 00099 CRITICAL_SECTION mutex; 00100 #else 00101 #ifndef __PTH__ 00102 class __LOCAL attribute 00103 { 00104 public: 00105 pthread_condattr_t attr; 00106 attribute(); 00107 }; 00108 00109 __LOCAL static attribute attr; 00110 #endif 00111 00112 pthread_cond_t cond; 00113 pthread_mutex_t mutex; 00114 #endif 00115 00116 protected: 00117 friend class TimedEvent; 00118 00124 bool wait(timeout_t timeout); 00125 00131 bool wait(struct timespec *timeout); 00132 00133 #ifdef _MSWINDOWS_ 00134 inline void lock(void) 00135 {EnterCriticalSection(&mutex);}; 00136 00137 inline void unlock(void) 00138 {LeaveCriticalSection(&mutex);}; 00139 00140 void wait(void); 00141 void signal(void); 00142 void broadcast(void); 00143 00144 #else 00145 00148 inline void lock(void) 00149 {pthread_mutex_lock(&mutex);}; 00150 00154 inline void unlock(void) 00155 {pthread_mutex_unlock(&mutex);}; 00156 00160 inline void wait(void) 00161 {pthread_cond_wait(&cond, &mutex);}; 00162 00166 inline void signal(void) 00167 {pthread_cond_signal(&cond);}; 00168 00172 inline void broadcast(void) 00173 {pthread_cond_broadcast(&cond);}; 00174 #endif 00175 00179 Conditional(); 00180 00184 ~Conditional(); 00185 00186 public: 00187 #if !defined(_MSWINDOWS_) && !defined(__PTH__) 00188 00193 static inline pthread_condattr_t *initializer(void) 00194 {return &attr.attr;}; 00195 #endif 00196 00203 static void gettimeout(timeout_t timeout, struct timespec *hires); 00204 }; 00205 00213 class __EXPORT ConditionalAccess : private Conditional 00214 { 00215 protected: 00216 #if defined _MSCONDITIONAL_ 00217 CONDITION_VARIABLE bcast; 00218 #elif !defined(_MSWINDOWS_) 00219 pthread_cond_t bcast; 00220 #endif 00221 00222 unsigned pending, waiting, sharing; 00223 00229 bool waitSignal(timeout_t timeout); 00230 00236 bool waitBroadcast(timeout_t timeout); 00237 00238 00244 bool waitSignal(struct timespec *timeout); 00245 00251 bool waitBroadcast(struct timespec *timeout); 00252 00259 inline static void gettimeout(timeout_t timeout, struct timespec *hires) 00260 {Conditional::gettimeout(timeout, hires);}; 00261 00262 00263 #ifdef _MSWINDOWS_ 00264 inline void lock(void) 00265 {EnterCriticalSection(&mutex);}; 00266 00267 inline void unlock(void) 00268 {LeaveCriticalSection(&mutex);}; 00269 00270 void waitSignal(void); 00271 void waitBroadcast(void); 00272 00273 inline void signal(void) 00274 {Conditional::signal();}; 00275 00276 inline void broadcast(void) 00277 {Conditional::broadcast();}; 00278 00279 #else 00280 00283 inline void lock(void) 00284 {pthread_mutex_lock(&mutex);}; 00285 00289 inline void unlock(void) 00290 {pthread_mutex_unlock(&mutex);}; 00291 00295 inline void waitSignal(void) 00296 {pthread_cond_wait(&cond, &mutex);}; 00297 00301 inline void waitBroadcast(void) 00302 {pthread_cond_wait(&bcast, &mutex);}; 00303 00304 00308 inline void signal(void) 00309 {pthread_cond_signal(&cond);}; 00310 00314 inline void broadcast(void) 00315 {pthread_cond_broadcast(&bcast);}; 00316 #endif 00317 public: 00321 ConditionalAccess(); 00322 00326 ~ConditionalAccess(); 00327 00331 void access(void); 00332 00336 void modify(void); 00337 00341 void release(void); 00342 00346 void commit(void); 00347 00354 void limit_sharing(unsigned max); 00355 }; 00356 00365 class __EXPORT TimedEvent : public Timer 00366 { 00367 private: 00368 #ifdef _MSWINDOWS_ 00369 HANDLE event; 00370 #else 00371 pthread_cond_t cond; 00372 bool signalled; 00373 #endif 00374 pthread_mutex_t mutex; 00375 00376 protected: 00381 void lock(void); 00382 00387 void release(void); 00388 00396 bool sync(void); 00397 00398 public: 00402 TimedEvent(void); 00403 00408 TimedEvent(timeout_t timeout); 00409 00414 TimedEvent(time_t timeout); 00415 00419 ~TimedEvent(); 00420 00426 void signal(void); 00427 00434 bool wait(timeout_t timeout); 00435 00439 void wait(void); 00440 00444 void reset(void); 00445 00450 inline static void signal(TimedEvent& timed) 00451 {timed.signal();}; 00452 00457 inline static void reset(TimedEvent& timed) 00458 {timed.reset();}; 00459 00466 inline static bool wait(TimedEvent& timed, timeout_t timeout) 00467 {return timed.wait(timeout);}; 00468 }; 00469 00477 class __EXPORT RecursiveMutex : private Conditional, public ExclusiveProtocol 00478 { 00479 protected: 00480 unsigned waiting; 00481 unsigned lockers; 00482 pthread_t locker; 00483 00484 void Exlock(void); 00485 void Unlock(void); 00486 00487 public: 00491 RecursiveMutex(); 00492 00496 void lock(void); 00497 00501 bool lock(timeout_t timeout); 00502 00506 void release(void); 00507 00512 unsigned getLocking(void); 00513 00518 unsigned getWaiting(void); 00519 00524 inline static void lock(RecursiveMutex& rex) 00525 {rex.lock();}; 00526 00531 inline static void release(RecursiveMutex& rex) 00532 {rex.release();}; 00533 }; 00534 00547 class __EXPORT ThreadLock : private ConditionalAccess, public ExclusiveProtocol, public SharedProtocol 00548 { 00549 protected: 00550 unsigned writers; 00551 pthread_t writeid; 00552 00553 void Exlock(void); 00554 void Shlock(void); 00555 void Unlock(void); 00556 00557 public: 00565 class __EXPORT gaurd_reader 00566 { 00567 private: 00568 void *object; 00569 00570 public: 00575 gaurd_reader(); 00576 00581 gaurd_reader(void *object); 00582 00586 ~gaurd_reader(); 00587 00593 void set(void *object); 00594 00598 void release(void); 00599 00605 inline void operator=(void *pointer) 00606 {set(pointer);}; 00607 }; 00608 00616 class __EXPORT gaurd_writer 00617 { 00618 private: 00619 void *object; 00620 00621 public: 00626 gaurd_writer(); 00627 00632 gaurd_writer(void *object); 00633 00637 ~gaurd_writer(); 00638 00644 void set(void *object); 00645 00649 void release(void); 00650 00656 inline void operator=(void *pointer) 00657 {set(pointer);}; 00658 }; 00659 00663 ThreadLock(); 00664 00670 bool modify(timeout_t timeout = Timer::inf); 00671 00677 bool access(timeout_t timeout = Timer::inf); 00678 00685 static void indexing(unsigned size); 00686 00694 static bool writer(void *object, timeout_t timeout = Timer::inf); 00695 00703 static bool reader(void *object, timeout_t timeout = Timer::inf); 00704 00709 static void release(void *object); 00710 00714 void release(void); 00715 00720 unsigned getAccess(void); 00721 00726 unsigned getModify(void); 00727 00732 unsigned getWaiting(void); 00733 00740 inline static bool modify(ThreadLock& lock, timeout_t timeout = Timer::inf) 00741 {return lock.modify(timeout);}; 00742 00749 inline static bool access(ThreadLock& lock, timeout_t timeout = Timer::inf) 00750 {return lock.access(timeout);}; 00751 00756 inline static void release(ThreadLock& lock) 00757 {lock.release();}; 00758 }; 00759 00770 class __EXPORT ReusableAllocator : protected Conditional 00771 { 00772 protected: 00773 ReusableObject *freelist; 00774 unsigned waiting; 00775 00779 ReusableAllocator(); 00780 00786 inline ReusableObject *next(ReusableObject *object) 00787 {return object->getNext();}; 00788 00793 void release(ReusableObject *object); 00794 }; 00795 00806 class __EXPORT ConditionalLock : protected ConditionalAccess, public SharedProtocol 00807 { 00808 protected: 00809 class Context : public LinkedObject 00810 { 00811 public: 00812 inline Context(LinkedObject **root) : LinkedObject(root) {}; 00813 00814 pthread_t thread; 00815 unsigned count; 00816 }; 00817 00818 LinkedObject *contexts; 00819 00820 void Shlock(void); 00821 void Unlock(void); 00822 void Exclusive(void); 00823 void Share(void); 00824 Context *getContext(void); 00825 00826 public: 00830 ConditionalLock(); 00831 00835 ~ConditionalLock(); 00836 00840 void modify(void); 00841 00845 void commit(void); 00846 00850 void access(void); 00851 00855 void release(void); 00856 00861 void exclusive(void); 00862 00866 void share(void); 00867 00871 unsigned getReaders(void); 00872 00876 unsigned getWaiters(void); 00877 00882 inline static void modify(ConditionalLock& lock) 00883 {lock.modify();}; 00884 00889 inline static void commit(ConditionalLock& lock) 00890 {lock.commit();}; 00891 00896 inline static void release(ConditionalLock& lock) 00897 {lock.release();}; 00898 00903 inline static void access(ConditionalLock& lock) 00904 {lock.access();}; 00905 00910 inline static void exclusive(ConditionalLock& lock) 00911 {lock.exclusive();}; 00912 00917 inline static void share(ConditionalLock& lock) 00918 {lock.share();}; 00919 }; 00920 00933 class __EXPORT barrier : private Conditional 00934 { 00935 private: 00936 unsigned count; 00937 unsigned waits; 00938 00939 public: 00944 barrier(unsigned count); 00945 00949 ~barrier(); 00950 00956 void set(unsigned count); 00957 00961 void inc(void); 00962 00966 void dec(void); 00967 00972 unsigned operator++(void); 00973 00974 unsigned operator--(void); 00975 00979 void wait(void); 00980 00987 bool wait(timeout_t timeout); 00988 00993 inline static void wait(barrier& sync) 00994 {sync.wait();}; 00995 01002 inline static bool wait(barrier& sync, timeout_t timeout) 01003 {return sync.wait(timeout);}; 01004 01005 01011 inline static void set(barrier& sync, unsigned count) 01012 {sync.set(count);}; 01013 }; 01014 01023 class __EXPORT Semaphore : public SharedProtocol, protected Conditional 01024 { 01025 protected: 01026 unsigned count, waits, used; 01027 01028 void Shlock(void); 01029 void Unlock(void); 01030 01031 public: 01035 Semaphore(unsigned count = 0); 01036 01041 void wait(void); 01042 01050 bool wait(timeout_t timeout); 01051 01056 unsigned getCount(void); 01057 01062 unsigned getUsed(void); 01063 01068 void set(unsigned count); 01069 01073 void release(void); 01074 01078 inline void operator++(void) 01079 {wait();}; 01080 01084 inline void operator--(void) 01085 {release();}; 01086 01091 inline static void wait(Semaphore& sync) 01092 {sync.wait();}; 01093 01100 inline static bool wait(Semaphore& sync, timeout_t timeout) 01101 {return sync.wait(timeout);}; 01102 01107 inline static void release(Semaphore& sync) 01108 {sync.release();}; 01109 }; 01110 01124 class __EXPORT Mutex : public ExclusiveProtocol 01125 { 01126 protected: 01127 pthread_mutex_t mlock; 01128 01129 void Exlock(void); 01130 void Unlock(void); 01131 01132 public: 01140 class __EXPORT gaurd 01141 { 01142 private: 01143 void *object; 01144 01145 public: 01150 gaurd(); 01151 01156 gaurd(void *object); 01157 01161 ~gaurd(); 01162 01168 void set(void *object); 01169 01173 void release(void); 01174 01180 inline void operator=(void *pointer) 01181 {set(pointer);}; 01182 }; 01183 01184 01188 Mutex(); 01189 01193 ~Mutex(); 01194 01198 inline void acquire(void) 01199 {pthread_mutex_lock(&mlock);}; 01200 01204 inline void lock(void) 01205 {pthread_mutex_lock(&mlock);}; 01206 01210 inline void unlock(void) 01211 {pthread_mutex_unlock(&mlock);}; 01212 01216 inline void release(void) 01217 {pthread_mutex_unlock(&mlock);}; 01218 01223 inline static void acquire(Mutex& lock) 01224 {pthread_mutex_lock(&lock.mlock);}; 01225 01230 inline static void lock(Mutex& lock) 01231 {pthread_mutex_lock(&lock.mlock);}; 01232 01237 inline static void unlock(Mutex& lock) 01238 {pthread_mutex_unlock(&lock.mlock);}; 01239 01244 inline static void release(Mutex& lock) 01245 {pthread_mutex_unlock(&lock.mlock);}; 01246 01251 inline static void acquire(pthread_mutex_t *lock) 01252 {pthread_mutex_lock(lock);}; 01253 01258 inline static void lock(pthread_mutex_t *lock) 01259 {pthread_mutex_lock(lock);}; 01260 01265 inline static void unlock(pthread_mutex_t *lock) 01266 {pthread_mutex_unlock(lock);}; 01267 01272 inline static void release(pthread_mutex_t *lock) 01273 {pthread_mutex_unlock(lock);}; 01274 01281 static void indexing(unsigned size); 01282 01288 static void protect(void *pointer); 01289 01294 static void release(void *pointer); 01295 }; 01296 01305 class __EXPORT auto_protect 01306 { 01307 private: 01308 // cannot copy... 01309 inline auto_protect(const auto_object &pointer) {}; 01310 01311 protected: 01312 void *object; 01313 01314 auto_protect(); 01315 01316 public: 01321 auto_protect(void *object); 01322 01327 ~auto_protect(); 01328 01332 void release(void); 01333 01338 inline bool operator!() const 01339 {return object == NULL;}; 01340 01345 inline operator bool() const 01346 {return object != NULL;}; 01347 01354 void operator=(void *object); 01355 }; 01356 01368 class __EXPORT LockedPointer 01369 { 01370 private: 01371 friend class locked_release; 01372 pthread_mutex_t mutex; 01373 ObjectProtocol *pointer; 01374 01375 protected: 01379 LockedPointer(); 01380 01385 void replace(ObjectProtocol *object); 01386 01391 ObjectProtocol *dup(void); 01392 01397 inline void operator=(ObjectProtocol *object) 01398 {replace(object);}; 01399 }; 01400 01409 class __EXPORT SharedObject 01410 { 01411 protected: 01412 friend class SharedPointer; 01413 01422 virtual void commit(SharedPointer *pointer); 01423 01424 public: 01428 virtual ~SharedObject(); 01429 }; 01430 01441 class __EXPORT SharedPointer : protected ConditionalAccess 01442 { 01443 private: 01444 friend class shared_release; 01445 SharedObject *pointer; 01446 01447 protected: 01451 SharedPointer(); 01452 01456 ~SharedPointer(); 01457 01464 void replace(SharedObject *object); 01465 01472 SharedObject *share(void); 01473 }; 01474 01485 class __EXPORT Thread 01486 { 01487 protected: 01488 // may be used in future if we need cancelable threads... 01489 #ifdef _MSWINDOWS_ 01490 HANDLE cancellor; 01491 #else 01492 void *cancellor; 01493 #endif 01494 01495 enum {} reserved; // cancel mode? 01496 pthread_t tid; 01497 size_t stack; 01498 int priority; 01499 01505 Thread(size_t stack = 0); 01506 01511 void map(void); 01512 01513 public: 01520 void setPriority(void); 01521 01526 static void yield(void); 01527 01532 static void sleep(timeout_t timeout); 01533 01540 static Thread *get(void); 01541 01545 virtual void run(void) = 0; 01546 01550 virtual ~Thread(); 01551 01560 virtual void exit(void); 01561 01565 static void init(void); 01566 01572 static void policy(int polid); 01573 01578 static void concurrency(int level); 01579 01586 static bool equal(pthread_t thread1, pthread_t thread2); 01587 01592 static pthread_t self(void); 01593 01597 virtual bool isRunning(void); 01598 01599 inline operator bool() 01600 {return isRunning();} 01601 }; 01602 01613 class __EXPORT JoinableThread : protected Thread 01614 { 01615 protected: 01616 #ifdef _MSWINDOWS_ 01617 HANDLE running; 01618 #else 01619 volatile bool running; 01620 #endif 01621 volatile bool joining; 01622 01627 JoinableThread(size_t size = 0); 01628 01633 virtual ~JoinableThread(); 01634 01640 void join(void); 01641 01642 public: 01643 bool isRunning(void); 01644 01653 void start(int priority = 0); 01654 01659 inline void background(void) 01660 {start(-1);}; 01661 }; 01662 01670 class __EXPORT DetachedThread : protected Thread 01671 { 01672 protected: 01673 bool active; 01674 01679 DetachedThread(size_t size = 0); 01680 01686 ~DetachedThread(); 01687 01696 void exit(void); 01697 01698 public: 01705 void start(int priority = 0); 01706 01707 bool isRunning(void); 01708 }; 01709 01718 class __EXPORT locked_release 01719 { 01720 protected: 01721 ObjectProtocol *object; 01726 locked_release(); 01727 01733 locked_release(const locked_release &object); 01734 01735 public: 01741 locked_release(LockedPointer &pointer); 01742 01747 ~locked_release(); 01748 01752 void release(void); 01753 01759 locked_release &operator=(LockedPointer &pointer); 01760 }; 01761 01771 class __EXPORT shared_release 01772 { 01773 protected: 01774 SharedPointer *ptr; 01779 shared_release(); 01780 01786 shared_release(const shared_release &object); 01787 01788 public: 01793 shared_release(SharedPointer &pointer); 01794 01800 ~shared_release(); 01801 01805 void release(void); 01806 01811 SharedObject *get(void); 01812 01818 shared_release &operator=(SharedPointer &pointer); 01819 }; 01820 01828 template<class T> 01829 class shared_pointer : public SharedPointer 01830 { 01831 public: 01835 inline shared_pointer() : SharedPointer() {}; 01836 01844 inline const T *dup(void) 01845 {return static_cast<const T*>(SharedPointer::share());}; 01846 01853 inline void replace(T *object) 01854 {SharedPointer::replace(object);}; 01855 01860 inline void operator=(T *object) 01861 {replace(object);}; 01862 01867 inline T *operator*() 01868 {return dup();}; 01869 }; 01870 01878 template<class T> 01879 class locked_pointer : public LockedPointer 01880 { 01881 public: 01885 inline locked_pointer() : LockedPointer() {}; 01886 01892 inline T* dup(void) 01893 {return static_cast<T *>(LockedPointer::dup());}; 01894 01899 inline void replace(T *object) 01900 {LockedPointer::replace(object);}; 01901 01906 inline void operator=(T *object) 01907 {replace(object);}; 01908 01914 inline T *operator*() 01915 {return dup();}; 01916 }; 01917 01923 template<class T> 01924 class locked_instance : public locked_release 01925 { 01926 public: 01930 inline locked_instance() : locked_release() {}; 01931 01936 inline locked_instance(locked_pointer<T> &pointer) : locked_release(pointer) {}; 01937 01942 inline T& operator*() const 01943 {return *(static_cast<T *>(object));}; 01944 01949 inline T* operator->() const 01950 {return static_cast<T*>(object);}; 01951 01956 inline T* get(void) const 01957 {return static_cast<T*>(object);}; 01958 }; 01959 01965 template<class T> 01966 class shared_instance : public shared_release 01967 { 01968 public: 01972 inline shared_instance() : shared_release() {}; 01973 01979 inline shared_instance(shared_pointer<T> &pointer) : shared_release(pointer) {}; 01980 01984 inline const T& operator*() const 01985 {return *(static_cast<const T *>(ptr->pointer));}; 01986 01991 inline const T* operator->() const 01992 {return static_cast<const T*>(ptr->pointer);}; 01993 01998 inline const T* get(void) const 01999 {return static_cast<const T*>(ptr->pointer);}; 02000 }; 02001 02008 template <class T> 02009 class mutex_pointer : public auto_protect 02010 { 02011 public: 02015 inline mutex_pointer() : auto_protect() {}; 02016 02021 inline mutex_pointer(T* object) : auto_protect(object) {}; 02022 02027 inline T& operator*() const 02028 {return *(static_cast<T*>(auto_protect::object));}; 02029 02034 inline T* operator->() const 02035 {return static_cast<T*>(auto_protect::object);}; 02036 02041 inline T* get(void) const 02042 {return static_cast<T*>(auto_protect::object);}; 02043 }; 02044 02050 inline void start(JoinableThread *thread, int priority = 0) 02051 {thread->start(priority);} 02052 02058 inline void start(DetachedThread *thread, int priority = 0) 02059 {thread->start(priority);} 02060 02064 typedef ConditionalLock condlock_t; 02065 02069 typedef ConditionalAccess accesslock_t; 02070 02074 typedef TimedEvent timedevent_t; 02075 02079 typedef Mutex mutex_t; 02080 02084 typedef ThreadLock rwlock_t; 02085 02089 typedef RecursiveMutex rexlock_t; 02090 02094 typedef Semaphore semaphore_t; 02095 02099 typedef barrier barrier_t; 02100 02105 inline void wait(barrier_t &barrier) 02106 {barrier.wait();} 02107 02113 inline void wait(semaphore_t &semaphore, timeout_t timeout = Timer::inf) 02114 {semaphore.wait(timeout);} 02115 02120 inline void release(semaphore_t &semaphore) 02121 {semaphore.release();} 02122 02127 inline void acquire(mutex_t &mutex) 02128 {mutex.lock();} 02129 02134 inline void release(mutex_t &mutex) 02135 {mutex.release();} 02136 02141 inline void modify(accesslock_t &lock) 02142 {lock.modify();} 02143 02148 inline void access(accesslock_t &lock) 02149 {lock.access();} 02150 02155 inline void release(accesslock_t &lock) 02156 {lock.release();} 02157 02163 inline void commit(accesslock_t &lock) 02164 {lock.commit();} 02165 02170 inline void exclusive(condlock_t &lock) 02171 {lock.exclusive();} 02172 02177 inline void share(condlock_t &lock) 02178 {lock.share();} 02179 02184 inline void modify(condlock_t &lock) 02185 {lock.modify();} 02186 02192 inline void commit(condlock_t &lock) 02193 {lock.commit();} 02194 02199 inline void access(condlock_t &lock) 02200 {lock.access();} 02201 02206 inline void release(condlock_t &lock) 02207 {lock.release();} 02208 02214 inline bool exclusive(rwlock_t &lock, timeout_t timeout = Timer::inf) 02215 {return lock.modify(timeout);} 02216 02222 inline bool share(rwlock_t &lock, timeout_t timeout = Timer::inf) 02223 {return lock.access(timeout);} 02224 02229 inline void release(rwlock_t &lock) 02230 {lock.release();} 02231 02236 inline void lock(rexlock_t &lock) 02237 {lock.lock();} 02238 02243 inline void release(rexlock_t &lock) 02244 {lock.release();} 02245 02246 END_NAMESPACE 02247 02248 #define ENTER_EXCLUSIVE \ 02249 do { static pthread_mutex_t __sync__ = PTHREAD_MUTEX_INITIALIZER; \ 02250 pthread_mutex_lock(&__sync__); 02251 02252 #define LEAVE_EXCLUSIVE \ 02253 pthread_mutex_unlock(&__sync__);} while(0); 02254 02255 #endif