ucommon

ucommon/thread.h

Go to the documentation of this file.
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_CONFIG_H_
00057 #include <ucommon/platform.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 #ifdef  _MSWINDOWS_
00092     enum {SIGNAL = 0, BROADCAST = 1};
00093     HANDLE events[2];
00094     unsigned waiting;
00095     CRITICAL_SECTION mlock;
00096     CRITICAL_SECTION mutex;
00097 #else
00098 #ifndef __PTH__
00099     class __LOCAL attribute
00100     {
00101     public:
00102         pthread_condattr_t attr;
00103         attribute();
00104     };
00105 
00106     __LOCAL static attribute attr;
00107 #endif
00108 
00109     pthread_cond_t cond;
00110     pthread_mutex_t mutex;
00111 #endif
00112 
00113 protected:
00114     friend class TimedEvent;
00115 
00121     bool wait(timeout_t timeout);
00122 
00128     bool wait(struct timespec *timeout);
00129 
00130 #ifdef  _MSWINDOWS_
00131     inline void lock(void)
00132         {EnterCriticalSection(&mutex);};
00133 
00134     inline void unlock(void)
00135         {LeaveCriticalSection(&mutex);};
00136 
00137     void wait(void);
00138     void signal(void);
00139     void broadcast(void);
00140 
00141 #else
00142 
00145     inline void lock(void)
00146         {pthread_mutex_lock(&mutex);};
00147 
00151     inline void unlock(void)
00152         {pthread_mutex_unlock(&mutex);};
00153 
00157     inline void wait(void)
00158         {pthread_cond_wait(&cond, &mutex);};
00159 
00163     inline void signal(void)
00164         {pthread_cond_signal(&cond);};
00165 
00169     inline void broadcast(void)
00170         {pthread_cond_broadcast(&cond);};
00171 #endif
00172 
00176     Conditional();
00177 
00181     ~Conditional();
00182 
00183 public:
00184 #if !defined(_MSWINDOWS_) && !defined(__PTH__)
00185 
00190     static inline pthread_condattr_t *initializer(void)
00191         {return &attr.attr;};
00192 #endif
00193 
00200     static void gettimeout(timeout_t timeout, struct timespec *hires);
00201 };
00202 
00210 class __EXPORT ConditionalAccess : private Conditional
00211 {
00212 private:
00213 #ifndef _MSWINDOWS_
00214     pthread_cond_t bcast;
00215 #endif
00216 
00217 protected:
00218     unsigned pending, waiting, sharing;
00219 
00225     bool waitSignal(timeout_t timeout);
00226 
00232     bool waitBroadcast(timeout_t timeout);
00233 
00234 
00240     bool waitSignal(struct timespec *timeout);
00241 
00247     bool waitBroadcast(struct timespec *timeout);
00248 
00255     inline static void gettimeout(timeout_t timeout, struct timespec *hires)
00256         {Conditional::gettimeout(timeout, hires);};
00257 
00258 
00259 #ifdef  _MSWINDOWS_
00260     inline void lock(void)
00261         {EnterCriticalSection(&mutex);};
00262 
00263     inline void unlock(void)
00264         {LeaveCriticalSection(&mutex);};
00265 
00266     void waitSignal(void);
00267     void waitBroadcast(void);
00268 
00269     inline void signal(void)
00270         {Conditional::signal();};
00271 
00272     inline void broadcast(void)
00273         {Conditional::broadcast();};
00274 
00275 #else
00276 
00279     inline void lock(void)
00280         {pthread_mutex_lock(&mutex);};
00281 
00285     inline void unlock(void)
00286         {pthread_mutex_unlock(&mutex);};
00287 
00291     inline void waitSignal(void)
00292         {pthread_cond_wait(&cond, &mutex);};
00293 
00297     inline void waitBroadcast(void)
00298         {pthread_cond_wait(&bcast, &mutex);};
00299 
00300 
00304     inline void signal(void)
00305         {pthread_cond_signal(&cond);};
00306 
00310     inline void broadcast(void)
00311         {pthread_cond_broadcast(&bcast);};
00312 #endif
00313 public:
00317     ConditionalAccess();
00318 
00322     ~ConditionalAccess();
00323 
00327     void access(void);
00328 
00332     void modify(void);
00333 
00337     void release(void);
00338 
00342     void commit(void);
00343 
00350     void limit_sharing(unsigned max);
00351 };
00352 
00361 class __EXPORT TimedEvent : public Timer
00362 {
00363 private:
00364 #ifdef _MSWINDOWS_
00365     HANDLE event;
00366 #else
00367     pthread_cond_t cond;
00368     bool signalled;
00369 #endif
00370     pthread_mutex_t mutex;
00371 
00372 protected:
00377     void lock(void);
00378 
00383     void release(void);
00384 
00392     bool sync(void);
00393 
00394 public:
00398     TimedEvent(void);
00399 
00404     TimedEvent(timeout_t timeout);
00405 
00410     TimedEvent(time_t timeout);
00411 
00415     ~TimedEvent();
00416 
00422     void signal(void);
00423 
00430     bool wait(timeout_t timeout);
00431 
00435     void reset(void);
00436 
00441     inline static void signal(TimedEvent& timed)
00442         {timed.signal();};
00443 
00448     inline static void reset(TimedEvent& timed)
00449         {timed.reset();};
00450 
00457     inline static bool wait(TimedEvent& timed, timeout_t timeout)
00458         {return timed.wait(timeout);};
00459 };
00460 
00468 class __EXPORT rexlock : private Conditional, public Exclusive
00469 {
00470 private:
00471     unsigned waiting;
00472     unsigned lockers;
00473     pthread_t locker;
00474 
00475     __LOCAL void Exlock(void);
00476     __LOCAL void Unlock(void);
00477 
00478 public:
00482     rexlock();
00483 
00487     void lock(void);
00488 
00492     bool lock(timeout_t timeout);
00493 
00497     void release(void);
00498 
00503     unsigned getLocking(void);
00504 
00509     unsigned getWaiting(void);
00510 
00515     inline static void lock(rexlock& rex)
00516         {rex.lock();};
00517 
00522     inline static void release(rexlock& rex)
00523         {rex.release();};
00524 };
00525 
00538 class __EXPORT rwlock : private ConditionalAccess, public Exclusive, public Shared
00539 {
00540 private:
00541     unsigned writers;
00542     pthread_t writeid;
00543 
00544     __LOCAL void Exlock(void);
00545     __LOCAL void Shlock(void);
00546     __LOCAL void Unlock(void);
00547 
00548 public:
00556     class __EXPORT gaurd_reader
00557     {
00558     private:
00559         void *object;
00560 
00561     public:
00566         gaurd_reader();
00567 
00572         gaurd_reader(void *object);
00573 
00577         ~gaurd_reader();
00578 
00584         void set(void *object);
00585 
00589         void release(void);
00590 
00596         inline void operator=(void *pointer)
00597             {set(pointer);};
00598     };
00599 
00607     class __EXPORT gaurd_writer
00608     {
00609     private:
00610         void *object;
00611 
00612     public:
00617         gaurd_writer();
00618 
00623         gaurd_writer(void *object);
00624 
00628         ~gaurd_writer();
00629 
00635         void set(void *object);
00636 
00640         void release(void);
00641 
00647         inline void operator=(void *pointer)
00648             {set(pointer);};
00649     };
00650 
00654     rwlock();
00655 
00661     bool modify(timeout_t timeout = Timer::inf);
00662 
00668     bool access(timeout_t timeout = Timer::inf);
00669 
00676     static void indexing(unsigned size);
00677 
00685     static bool writer(void *object, timeout_t timeout = Timer::inf);
00686 
00694     static bool reader(void *object, timeout_t timeout = Timer::inf);
00695 
00700     static void release(void *object);
00701 
00705     void release(void);
00706 
00711     unsigned getAccess(void);
00712 
00717     unsigned getModify(void);
00718 
00723     unsigned getWaiting(void);
00724 
00731     inline static bool modify(rwlock& lock, timeout_t timeout = Timer::inf)
00732         {return lock.modify(timeout);};
00733 
00740     inline static bool access(rwlock& lock, timeout_t timeout = Timer::inf)
00741         {return lock.access(timeout);};
00742 
00747     inline static void release(rwlock& lock)
00748         {lock.release();};
00749 };
00750 
00761 class __EXPORT ReusableAllocator : protected Conditional
00762 {
00763 protected:
00764     ReusableObject *freelist;
00765     unsigned waiting;
00766 
00770     ReusableAllocator();
00771 
00777     inline ReusableObject *next(ReusableObject *object)
00778         {return object->getNext();};
00779 
00784     void release(ReusableObject *object);
00785 };
00786 
00797 class __EXPORT ConditionalLock : protected ConditionalAccess, public Shared
00798 {
00799 private:
00800     class Context : public LinkedObject
00801     {
00802     public:
00803         inline Context(LinkedObject **root) : LinkedObject(root) {};
00804 
00805         pthread_t thread;
00806         unsigned count;
00807     };
00808 
00809     LinkedObject *contexts;
00810 
00811     __LOCAL void Shlock(void);
00812     __LOCAL void Unlock(void);
00813     __LOCAL void Exclusive(void);
00814     __LOCAL void Share(void);
00815     __LOCAL Context *getContext(void);
00816 
00817 public:
00821     ConditionalLock();
00822 
00826     ~ConditionalLock();
00827 
00831     void modify(void);
00832 
00836     void commit(void);
00837 
00841     void access(void);
00842 
00846     void release(void);
00847 
00852     void exclusive(void);
00853 
00857     void share(void);
00858 
00862     unsigned getReaders(void);
00863 
00867     unsigned getWaiters(void);
00868 
00873     inline static void modify(ConditionalLock& lock)
00874         {lock.modify();};
00875 
00880     inline static void commit(ConditionalLock& lock)
00881         {lock.commit();};
00882 
00887     inline static void release(ConditionalLock& lock)
00888         {lock.release();};
00889 
00894     inline static void access(ConditionalLock& lock)
00895         {lock.access();};
00896 
00901     inline static void exclusive(ConditionalLock& lock)
00902         {lock.exclusive();};
00903 
00908     inline static void share(ConditionalLock& lock)
00909         {lock.share();};
00910 };
00911 
00924 class __EXPORT barrier : private Conditional
00925 {
00926 private:
00927     unsigned count;
00928     unsigned waits;
00929 
00930 public:
00935     barrier(unsigned count);
00936 
00940     ~barrier();
00941 
00947     void set(unsigned count);
00948 
00952     void inc(void);
00953 
00957     void dec(void);
00958 
00963     unsigned operator++(void);
00964 
00965     unsigned operator--(void);
00966 
00970     void wait(void);
00971 
00978     bool wait(timeout_t timeout);
00979 
00984     inline static void wait(barrier& sync)
00985         {sync.wait();};
00986 
00993     inline static bool wait(barrier& sync, timeout_t timeout)
00994         {return sync.wait(timeout);};
00995 
00996 
01002     inline static void set(barrier& sync, unsigned count)
01003         {sync.set(count);};
01004 };
01005 
01014 class __EXPORT semaphore : public Shared, private Conditional
01015 {
01016 private:
01017     unsigned count, waits, used;
01018 
01019     __LOCAL void Shlock(void);
01020     __LOCAL void Unlock(void);
01021 
01022 public:
01026     semaphore(unsigned count = 0);
01027 
01032     void wait(void);
01033 
01041     bool wait(timeout_t timeout);
01042 
01047     unsigned getCount(void);
01048 
01053     unsigned getUsed(void);
01054 
01059     void set(unsigned count);
01060 
01064     void release(void);
01065 
01069     inline void operator++(void)
01070         {wait();};
01071 
01075     inline void operator--(void)
01076         {release();};
01077 
01082     inline static void wait(semaphore& sync)
01083         {sync.wait();};
01084 
01091     inline static bool wait(semaphore& sync, timeout_t timeout)
01092         {return sync.wait(timeout);};
01093 
01098     inline static void release(semaphore& sync)
01099         {sync.release();};
01100 };
01101 
01115 class __EXPORT mutex : public Exclusive
01116 {
01117 private:
01118     pthread_mutex_t mlock;
01119 
01120     __LOCAL void Exlock(void);
01121     __LOCAL void Unlock(void);
01122 
01123 public:
01131     class __EXPORT gaurd
01132     {
01133     private:
01134         void *object;
01135 
01136     public:
01141         gaurd();
01142 
01147         gaurd(void *object);
01148 
01152         ~gaurd();
01153 
01159         void set(void *object);
01160 
01164         void release(void);
01165 
01171         inline void operator=(void *pointer)
01172             {set(pointer);};
01173     };
01174 
01175 
01179     mutex();
01180 
01184     ~mutex();
01185 
01189     inline void acquire(void)
01190         {pthread_mutex_lock(&mlock);};
01191 
01195     inline void lock(void)
01196         {pthread_mutex_lock(&mlock);};
01197 
01201     inline void unlock(void)
01202         {pthread_mutex_unlock(&mlock);};
01203 
01207     inline void release(void)
01208         {pthread_mutex_unlock(&mlock);};
01209 
01214     inline static void acquire(mutex& lock)
01215         {pthread_mutex_lock(&lock.mlock);};
01216 
01221     inline static void lock(mutex& lock)
01222         {pthread_mutex_lock(&lock.mlock);};
01223 
01228     inline static void unlock(mutex& lock)
01229         {pthread_mutex_unlock(&lock.mlock);};
01230 
01235     inline static void release(mutex& lock)
01236         {pthread_mutex_unlock(&lock.mlock);};
01237 
01242     inline static void acquire(pthread_mutex_t *lock)
01243         {pthread_mutex_lock(lock);};
01244 
01249     inline static void lock(pthread_mutex_t *lock)
01250         {pthread_mutex_lock(lock);};
01251 
01256     inline static void unlock(pthread_mutex_t *lock)
01257         {pthread_mutex_unlock(lock);};
01258 
01263     inline static void release(pthread_mutex_t *lock)
01264         {pthread_mutex_unlock(lock);};
01265 
01272     static void indexing(unsigned size);
01273 
01279     static void protect(void *pointer);
01280 
01285     static void release(void *pointer);
01286 };
01287 
01296 class __EXPORT auto_protect
01297 {
01298 private:
01299     // cannot copy...
01300     inline auto_protect(const auto_object &pointer) {};
01301 
01302 protected:
01303     void *object;
01304 
01305     auto_protect();
01306 
01307 public:
01312     auto_protect(void *object);
01313 
01318     ~auto_protect();
01319 
01323     void release(void);
01324 
01329     inline bool operator!() const
01330         {return object == NULL;};
01331 
01336     inline operator bool() const
01337         {return object != NULL;};
01338 
01345     void operator=(void *object);
01346 };
01347 
01359 class __EXPORT LockedPointer
01360 {
01361 private:
01362     friend class locked_release;
01363     pthread_mutex_t mutex;
01364     Object *pointer;
01365 
01366 protected:
01370     LockedPointer();
01371 
01376     void replace(Object *object);
01377 
01382     Object *dup(void);
01383 
01388     inline void operator=(Object *object)
01389         {replace(object);};
01390 };
01391 
01400 class __EXPORT SharedObject
01401 {
01402 protected:
01403     friend class SharedPointer;
01404 
01413     virtual void commit(SharedPointer *pointer);
01414 
01415 public:
01419     virtual ~SharedObject();
01420 };
01421 
01432 class __EXPORT SharedPointer : protected ConditionalAccess
01433 {
01434 private:
01435     friend class shared_release;
01436     SharedObject *pointer;
01437 
01438 protected:
01442     SharedPointer();
01443 
01447     ~SharedPointer();
01448 
01455     void replace(SharedObject *object);
01456 
01463     SharedObject *share(void);
01464 };
01465 
01476 class __EXPORT Thread
01477 {
01478 protected:
01479     pthread_t tid;
01480     size_t stack;
01481     int priority;
01482 
01488     Thread(size_t stack = 0);
01489 
01494     void map(void);
01495 
01496 public:
01503     void setPriority(void);
01504 
01509     static void yield(void);
01510 
01515     static void sleep(timeout_t timeout);
01516 
01523     static Thread *get(void);
01524 
01528     virtual void run(void) = 0;
01529 
01533     virtual ~Thread();
01534 
01543     virtual void exit(void);
01544 
01548     static void init(void);
01549 
01555     static void policy(int polid);
01556 
01561     static void concurrency(int level);
01562 
01569     static bool equal(pthread_t thread1, pthread_t thread2);
01570 
01575     static pthread_t self(void);
01576 };
01577 
01588 class __EXPORT JoinableThread : protected Thread
01589 {
01590 protected:
01591 #ifdef  _MSWINDOWS_
01592     HANDLE joining;
01593 #else
01594     volatile bool running;
01595 #endif
01596 
01601     JoinableThread(size_t size = 0);
01602 
01607     virtual ~JoinableThread();
01608 
01614     void join(void);
01615 
01616 public:
01617 #ifdef  _MSWINDOWS_
01618     inline bool isRunning(void)
01619         {return (joining != INVALID_HANDLE_VALUE);};
01620 #else
01621 
01625     inline bool isRunning(void)
01626         {return running;};
01627 #endif
01628 
01637     void start(int priority = 0);
01638 
01643     inline void background(void)
01644         {start(-1);};
01645 };
01646 
01654 class __EXPORT DetachedThread : protected Thread
01655 {
01656 protected:
01661     DetachedThread(size_t size = 0);
01662 
01668     ~DetachedThread();
01669 
01678     void exit(void);
01679 
01680 public:
01687     void start(int priority = 0);
01688 };
01689 
01698 class __EXPORT locked_release
01699 {
01700 protected:
01701     Object *object; 
01706     locked_release();
01707 
01713     locked_release(const locked_release &object);
01714 
01715 public:
01721     locked_release(LockedPointer &pointer);
01722 
01727     ~locked_release();
01728 
01732     void release(void);
01733 
01739     locked_release &operator=(LockedPointer &pointer);
01740 };
01741 
01751 class __EXPORT shared_release
01752 {
01753 protected:
01754     SharedPointer *ptr; 
01759     shared_release();
01760 
01766     shared_release(const shared_release &object);
01767 
01768 public:
01773     shared_release(SharedPointer &pointer);
01774 
01780     ~shared_release();
01781 
01785     void release(void);
01786 
01791     SharedObject *get(void);
01792 
01798     shared_release &operator=(SharedPointer &pointer);
01799 };
01800 
01808 template<class T>
01809 class shared_pointer : public SharedPointer
01810 {
01811 public:
01815     inline shared_pointer() : SharedPointer() {};
01816 
01824     inline const T *dup(void)
01825         {return static_cast<const T*>(SharedPointer::share());};
01826 
01833     inline void replace(T *object)
01834         {SharedPointer::replace(object);};
01835 
01840     inline void operator=(T *object)
01841         {replace(object);};
01842 
01847     inline T *operator*()
01848         {return dup();};
01849 };
01850 
01858 template<class T>
01859 class locked_pointer : public LockedPointer
01860 {
01861 public:
01865     inline locked_pointer() : LockedPointer() {};
01866 
01872     inline T* dup(void)
01873         {return static_cast<T *>(LockedPointer::dup());};
01874 
01879     inline void replace(T *object)
01880         {LockedPointer::replace(object);};
01881 
01886     inline void operator=(T *object)
01887         {replace(object);};
01888 
01894     inline T *operator*()
01895         {return dup();};
01896 };
01897 
01903 template<class T>
01904 class locked_instance : public locked_release
01905 {
01906 public:
01910     inline locked_instance() : locked_release() {};
01911 
01916     inline locked_instance(locked_pointer<T> &pointer) : locked_release(pointer) {};
01917 
01922     inline T& operator*() const
01923         {return *(static_cast<T *>(object));};
01924 
01929     inline T* operator->() const
01930         {return static_cast<T*>(object);};
01931 
01936     inline T* get(void) const
01937         {return static_cast<T*>(object);};
01938 };
01939 
01945 template<class T>
01946 class shared_instance : public shared_release
01947 {
01948 public:
01952     inline shared_instance() : shared_release() {};
01953 
01959     inline shared_instance(shared_pointer<T> &pointer) : shared_release(pointer) {};
01960 
01964     inline const T& operator*() const
01965         {return *(static_cast<const T *>(ptr->pointer));};
01966 
01971     inline const T* operator->() const
01972         {return static_cast<const T*>(ptr->pointer);};
01973 
01978     inline const T* get(void) const
01979         {return static_cast<const T*>(ptr->pointer);};
01980 };
01981 
01988 template <class T>
01989 class mutex_pointer : public auto_protect
01990 {
01991 public:
01995     inline mutex_pointer() : auto_protect() {};
01996 
02001     inline mutex_pointer(T* object) : auto_protect(object) {};
02002 
02007     inline T& operator*() const
02008         {return *(static_cast<T*>(auto_protect::object));};
02009 
02014     inline T* operator->() const
02015         {return static_cast<T*>(auto_protect::object);};
02016 
02021     inline T* get(void) const
02022         {return static_cast<T*>(auto_protect::object);};
02023 };
02024 
02030 inline void start(JoinableThread *thread, int priority = 0)
02031     {thread->start(priority);}
02032 
02038 inline void start(DetachedThread *thread, int priority = 0)
02039     {thread->start(priority);}
02040 
02044 typedef ConditionalLock condlock_t;
02045 
02049 typedef ConditionalAccess accesslock_t;
02050 
02054 typedef TimedEvent timedevent_t;
02055 
02059 typedef mutex mutex_t;
02060 
02065 typedef mutex Mutex;
02066 
02070 typedef rwlock rwlock_t;
02071 
02075 typedef rexlock rexlock_t;
02076 
02080 typedef semaphore semaphore_t;
02081 
02085 typedef barrier barrier_t;
02086 
02091 inline void wait(barrier_t &barrier)
02092     {barrier.wait();}
02093 
02099 inline void wait(semaphore_t &semaphore, timeout_t timeout = Timer::inf)
02100     {semaphore.wait(timeout);}
02101 
02106 inline void release(semaphore_t &semaphore)
02107     {semaphore.release();}
02108 
02113 inline void acquire(mutex_t &mutex)
02114     {mutex.lock();}
02115 
02120 inline void release(mutex_t &mutex)
02121     {mutex.release();}
02122 
02127 inline void modify(accesslock_t &lock)
02128     {lock.modify();}
02129 
02134 inline void access(accesslock_t &lock)
02135     {lock.access();}
02136 
02141 inline void release(accesslock_t &lock)
02142     {lock.release();}
02143 
02149 inline void commit(accesslock_t &lock)
02150     {lock.commit();}
02151 
02156 inline void exclusive(condlock_t &lock)
02157     {lock.exclusive();}
02158 
02163 inline void share(condlock_t &lock)
02164     {lock.share();}
02165 
02170 inline void modify(condlock_t &lock)
02171     {lock.modify();}
02172 
02178 inline void commit(condlock_t &lock)
02179     {lock.commit();}
02180 
02185 inline void access(condlock_t &lock)
02186     {lock.access();}
02187 
02192 inline void release(condlock_t &lock)
02193     {lock.release();}
02194 
02200 inline bool exclusive(rwlock_t &lock, timeout_t timeout = Timer::inf)
02201     {return lock.modify(timeout);}
02202 
02208 inline bool share(rwlock_t &lock, timeout_t timeout = Timer::inf)
02209     {return lock.access(timeout);}
02210 
02215 inline void release(rwlock_t &lock)
02216     {lock.release();}
02217 
02222 inline void lock(rexlock_t &lock)
02223     {lock.lock();}
02224 
02229 inline void release(rexlock_t &lock)
02230     {lock.release();}
02231 
02232 END_NAMESPACE
02233 
02234 #define ENTER_EXCLUSIVE \
02235     do { static pthread_mutex_t __sync__ = PTHREAD_MUTEX_INITIALIZER; \
02236         pthread_mutex_lock(&__sync__);
02237 
02238 #define LEAVE_EXCLUSIVE \
02239     pthread_mutex_unlock(&__sync__);} while(0);
02240 
02241 #endif