UCommon
/usr/src/RPM/BUILD/ucommon-6.3.3/inc/ucommon/thread.h
Go to the documentation of this file.
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 
00054 #ifndef _UCOMMON_THREAD_H_
00055 #define _UCOMMON_THREAD_H_
00056 
00057 #ifndef _UCOMMON_CPR_H_
00058 #include <ucommon/cpr.h>
00059 #endif
00060 
00061 #ifndef _UCOMMON_ACCESS_H_
00062 #include <ucommon/access.h>
00063 #endif
00064 
00065 #ifndef _UCOMMON_TIMERS_H_
00066 #include <ucommon/timers.h>
00067 #endif
00068 
00069 #ifndef _UCOMMON_MEMORY_H_
00070 #include <ucommon/memory.h>
00071 #endif
00072 
00073 namespace ucommon {
00074 
00075 class SharedPointer;
00076 
00087 class __EXPORT Conditional
00088 {
00089 private:
00090     friend class ConditionalAccess;
00091 
00092 #if defined(_MSCONDITIONAL_)
00093     mutable CRITICAL_SECTION mutex;
00094     mutable CONDITION_VARIABLE cond;
00095 #elif defined(_MSTHREADS_)
00096     enum {SIGNAL = 0, BROADCAST = 1};
00097     HANDLE events[2];
00098     unsigned waiting;
00099     mutable CRITICAL_SECTION mlock;
00100     mutable CRITICAL_SECTION mutex;
00101 #else
00102 #ifndef __PTH__
00103     class __LOCAL attribute
00104     {
00105     public:
00106         pthread_condattr_t attr;
00107         attribute();
00108     };
00109 
00110     __LOCAL static attribute attr;
00111 #endif
00112 
00113     mutable pthread_cond_t cond;
00114     mutable pthread_mutex_t mutex;
00115 #endif
00116 
00117 protected:
00118     friend class TimedEvent;
00119 
00125     bool wait(timeout_t timeout);
00126 
00132     bool wait(struct timespec *timeout);
00133 
00134 #ifdef  _MSTHREADS_
00135     inline void lock(void)
00136         {EnterCriticalSection(&mutex);};
00137 
00138     inline void unlock(void)
00139         {LeaveCriticalSection(&mutex);};
00140 
00141     void wait(void);
00142     void signal(void);
00143     void broadcast(void);
00144 
00145 #else
00146 
00149     inline void lock(void)
00150         {pthread_mutex_lock(&mutex);}
00151 
00155     inline void unlock(void)
00156         {pthread_mutex_unlock(&mutex);}
00157 
00161     inline void wait(void)
00162         {pthread_cond_wait(&cond, &mutex);}
00163 
00167     inline void signal(void)
00168         {pthread_cond_signal(&cond);}
00169 
00173     inline void broadcast(void)
00174         {pthread_cond_broadcast(&cond);}
00175 #endif
00176 
00180     Conditional();
00181 
00185     ~Conditional();
00186 
00187 public:
00188     friend class autolock;
00189 
00190     class __EXPORT autolock
00191     {
00192     private:
00193 #ifdef  _MSTHREADS_
00194         CRITICAL_SECTION *mutex;
00195 #else
00196         pthread_mutex_t *mutex;
00197 #endif
00198 
00199     public:
00200         inline autolock(const Conditional* object) {
00201             mutex = &object->mutex;
00202 #ifdef _MSTHREADS_
00203             EnterCriticalSection(mutex);
00204 #else
00205             pthread_mutex_lock(mutex);
00206 #endif
00207         }
00208 
00209         inline ~autolock() {
00210 #ifdef  _MSTHREADS_
00211             LeaveCriticalSection(mutex);
00212 #else
00213             pthread_mutex_unlock(mutex);
00214 #endif
00215         }
00216     };
00217 
00218 #if !defined(_MSTHREADS_) && !defined(__PTH__)
00219 
00224     static inline pthread_condattr_t *initializer(void)
00225         {return &attr.attr;}
00226 #endif
00227 
00234     static void set(struct timespec *hires, timeout_t timeout);
00235 };
00236 
00244 class __EXPORT ConditionalAccess : private Conditional
00245 {
00246 protected:
00247 #if defined _MSCONDITIONAL_
00248     CONDITION_VARIABLE bcast;
00249 #elif !defined(_MSTHREADS_)
00250     mutable pthread_cond_t bcast;
00251 #endif
00252 
00253     unsigned pending, waiting, sharing;
00254 
00260     bool waitSignal(timeout_t timeout);
00261 
00267     bool waitBroadcast(timeout_t timeout);
00268 
00269 
00275     bool waitSignal(struct timespec *timeout);
00276 
00282     bool waitBroadcast(struct timespec *timeout);
00283 
00290     inline static void set(struct timespec *hires, timeout_t timeout)
00291         {Conditional::set(hires, timeout);}
00292 
00293 
00294 #ifdef  _MSTHREADS_
00295     inline void lock(void)
00296         {EnterCriticalSection(&mutex);};
00297 
00298     inline void unlock(void)
00299         {LeaveCriticalSection(&mutex);};
00300 
00301     void waitSignal(void);
00302     void waitBroadcast(void);
00303 
00304     inline void signal(void)
00305         {Conditional::signal();};
00306 
00307     inline void broadcast(void)
00308         {Conditional::broadcast();};
00309 
00310 #else
00311 
00314     inline void lock(void)
00315         {pthread_mutex_lock(&mutex);}
00316 
00320     inline void unlock(void)
00321         {pthread_mutex_unlock(&mutex);}
00322 
00326     inline void waitSignal(void)
00327         {pthread_cond_wait(&cond, &mutex);}
00328 
00332     inline void waitBroadcast(void)
00333         {pthread_cond_wait(&bcast, &mutex);}
00334 
00335 
00339     inline void signal(void)
00340         {pthread_cond_signal(&cond);}
00341 
00345     inline void broadcast(void)
00346         {pthread_cond_broadcast(&bcast);}
00347 #endif
00348 public:
00352     ConditionalAccess();
00353 
00357     ~ConditionalAccess();
00358 
00362     void access(void);
00363 
00367     void modify(void);
00368 
00372     void release(void);
00373 
00377     void commit(void);
00378 
00385     void limit_sharing(unsigned max);
00386 };
00387 
00396 class __EXPORT TimedEvent : public Timer
00397 {
00398 private:
00399 #ifdef _MSTHREADS_
00400     HANDLE event;
00401 #else
00402     mutable pthread_cond_t cond;
00403     bool signalled;
00404 #endif
00405     mutable pthread_mutex_t mutex;
00406 
00407 protected:
00412     void lock(void);
00413 
00418     void release(void);
00419 
00427     bool sync(void);
00428 
00429 public:
00433     TimedEvent(void);
00434 
00439     TimedEvent(timeout_t timeout);
00440 
00445     TimedEvent(time_t timeout);
00446 
00450     ~TimedEvent();
00451 
00457     void signal(void);
00458 
00465     bool wait(timeout_t timeout);
00466 
00470     void wait(void);
00471 
00475     void reset(void);
00476 };
00477 
00485 class __EXPORT RecursiveMutex : private Conditional, public ExclusiveAccess
00486 {
00487 protected:
00488     unsigned waiting;
00489     unsigned lockers;
00490     pthread_t locker;
00491 
00492     virtual void _lock(void);
00493     virtual void _unlock(void);
00494 
00495 public:
00499     RecursiveMutex();
00500 
00504     void lock(void);
00505 
00509     bool lock(timeout_t timeout);
00510 
00514     void release(void);
00515 };
00516 
00529 class __EXPORT ThreadLock : private ConditionalAccess, public ExclusiveAccess, public SharedAccess
00530 {
00531 protected:
00532     unsigned writers;
00533     pthread_t writeid;
00534 
00535     virtual void _lock(void);
00536     virtual void _share(void);
00537     virtual void _unlock(void);
00538 
00539 public:
00547     class __EXPORT guard_reader
00548     {
00549     private:
00550         const void *object;
00551 
00552     public:
00557         guard_reader();
00558 
00563         guard_reader(const void *object);
00564 
00568         ~guard_reader();
00569 
00575         void set(const void *object);
00576 
00580         void release(void);
00581 
00587         inline void operator=(const void *pointer)
00588             {set(pointer);}
00589     };
00590 
00598     class __EXPORT guard_writer
00599     {
00600     private:
00601         const void *object;
00602 
00603     public:
00608         guard_writer();
00609 
00614         guard_writer(const void *object);
00615 
00619         ~guard_writer();
00620 
00626         void set(const void *object);
00627 
00631         void release(void);
00632 
00638         inline void operator=(const void *pointer)
00639             {set(pointer);}
00640     };
00641 
00645     ThreadLock();
00646 
00652     bool modify(timeout_t timeout = Timer::inf);
00653 
00659     bool access(timeout_t timeout = Timer::inf);
00660 
00667     static void indexing(unsigned size);
00668 
00676     static bool writer(const void *object, timeout_t timeout = Timer::inf);
00677 
00685     static bool reader(const void *object, timeout_t timeout = Timer::inf);
00686 
00691     static bool release(const void *object);
00692 
00696     void release(void);
00697 };
00698 
00709 class __EXPORT ReusableAllocator : protected Conditional
00710 {
00711 protected:
00712     ReusableObject *freelist;
00713     unsigned waiting;
00714 
00718     ReusableAllocator();
00719 
00725     inline ReusableObject *next(ReusableObject *object)
00726         {return object->getNext();}
00727 
00732     void release(ReusableObject *object);
00733 };
00734 
00745 class __EXPORT ConditionalLock : protected ConditionalAccess, public SharedAccess
00746 {
00747 protected:
00748     class Context : public LinkedObject
00749     {
00750     public:
00751         inline Context(LinkedObject **root) : LinkedObject(root) {}
00752 
00753         pthread_t thread;
00754         unsigned count;
00755     };
00756 
00757     LinkedObject *contexts;
00758 
00759     virtual void _share(void);
00760     virtual void _unlock(void);
00761 
00762     Context *getContext(void);
00763 
00764 public:
00768     ConditionalLock();
00769 
00773     ~ConditionalLock();
00774 
00778     void modify(void);
00779 
00783     void commit(void);
00784 
00788     void access(void);
00789 
00793     void release(void);
00794 
00799     virtual void exclusive(void);
00800 
00804     virtual void share(void);
00805 };
00806 
00819 class __EXPORT barrier : private Conditional
00820 {
00821 private:
00822     unsigned count;
00823     unsigned waits;
00824 
00825 public:
00830     barrier(unsigned count);
00831 
00835     ~barrier();
00836 
00842     void set(unsigned count);
00843 
00847     void inc(void);
00848 
00852     void dec(void);
00853 
00858     unsigned operator++(void);
00859 
00860     unsigned operator--(void);
00861 
00865     void wait(void);
00866 
00873     bool wait(timeout_t timeout);
00874 };
00875 
00884 class __EXPORT Semaphore : public SharedAccess, protected Conditional
00885 {
00886 protected:
00887     unsigned count, waits, used;
00888 
00889     virtual void _share(void);
00890     virtual void _unlock(void);
00891 
00892 public:
00897     Semaphore(unsigned count = 0);
00898 
00904     Semaphore(unsigned count, unsigned avail);
00905 
00910     void wait(void);
00911 
00919     bool wait(timeout_t timeout);
00920 
00925     void set(unsigned count);
00926 
00930     void release(void);
00931 
00935     inline void operator++(void)
00936         {wait();}
00937 
00941     inline void operator--(void)
00942         {release();}
00943 };
00944 
00958 class __EXPORT Mutex : public ExclusiveAccess
00959 {
00960 protected:
00961     mutable pthread_mutex_t mlock;
00962 
00963     virtual void _lock(void);
00964     virtual void _unlock(void);
00965 
00966 public:
00967     friend class autolock;
00968 
00969     class __EXPORT autolock
00970     {
00971     private:
00972         pthread_mutex_t *mutex;
00973 
00974     public:
00975         inline autolock(const Mutex *object) {
00976             mutex = &object->mlock;
00977             pthread_mutex_lock(this->mutex);
00978         }
00979 
00980         inline ~autolock() {
00981             pthread_mutex_unlock(this->mutex);
00982         }
00983     };
00984 
00992     class __EXPORT guard
00993     {
00994     private:
00995         const void *object;
00996 
00997     public:
01002         guard();
01003 
01008         guard(const void *object);
01009 
01013         ~guard();
01014 
01020         void set(const void *object);
01021 
01025         void release(void);
01026 
01032         inline void operator=(void *pointer)
01033             {set(pointer);}
01034     };
01035 
01036 
01040     Mutex();
01041 
01045     ~Mutex();
01046 
01050     inline void acquire(void)
01051         {pthread_mutex_lock(&mlock);}
01052 
01056     inline void lock(void)
01057         {pthread_mutex_lock(&mlock);}
01058 
01062     inline void unlock(void)
01063         {pthread_mutex_unlock(&mlock);}
01064 
01068     inline void release(void)
01069         {pthread_mutex_unlock(&mlock);}
01070 
01075     inline static void acquire(pthread_mutex_t *lock)
01076         {pthread_mutex_lock(lock);}
01077 
01082     inline static void release(pthread_mutex_t *lock)
01083         {pthread_mutex_unlock(lock);}
01084 
01091     static void indexing(unsigned size);
01092 
01098     static bool protect(const void *pointer);
01099 
01104     static bool release(const void *pointer);
01105 };
01106 
01115 class __EXPORT auto_protect
01116 {
01117 private:
01118     // cannot copy...
01119     inline auto_protect(const auto_object &pointer) {}
01120 
01121 protected:
01122     const void *object;
01123 
01124     auto_protect();
01125 
01126 public:
01131     auto_protect(const void *object);
01132 
01137     ~auto_protect();
01138 
01142     void release(void);
01143 
01148     inline bool operator!() const
01149         {return object == NULL;}
01150 
01155     inline operator bool() const
01156         {return object != NULL;}
01157 
01164     void operator=(const void *object);
01165 };
01166 
01178 class __EXPORT LockedPointer
01179 {
01180 private:
01181     friend class locked_release;
01182     mutable pthread_mutex_t mutex;
01183     ObjectProtocol *pointer;
01184 
01185 protected:
01189     LockedPointer();
01190 
01195     void replace(ObjectProtocol *object);
01196 
01201     ObjectProtocol *dup(void);
01202 
01207     inline void operator=(ObjectProtocol *object)
01208         {replace(object);}
01209 };
01210 
01219 class __EXPORT SharedObject
01220 {
01221 protected:
01222     friend class SharedPointer;
01223 
01232     virtual void commit(SharedPointer *pointer);
01233 
01234 public:
01238     virtual ~SharedObject();
01239 };
01240 
01251 class __EXPORT SharedPointer : protected ConditionalAccess
01252 {
01253 private:
01254     friend class shared_release;
01255     SharedObject *pointer;
01256 
01257 protected:
01261     SharedPointer();
01262 
01266     ~SharedPointer();
01267 
01274     void replace(SharedObject *object);
01275 
01282     SharedObject *share(void);
01283 };
01284 
01295 class __EXPORT Thread
01296 {
01297 protected:
01298 // may be used in future if we need cancelable threads...
01299 #ifdef  _MSTHREADS_
01300     HANDLE cancellor;
01301 #else
01302     void *cancellor;
01303 #endif
01304 
01305     enum {R_UNUSED} reserved;   // cancel mode?
01306     pthread_t tid;
01307     size_t stack;
01308     int priority;
01309 
01315     Thread(size_t stack = 0);
01316 
01321     void map(void);
01322 
01326     virtual bool is_active(void) const;
01327 
01328 public:
01335     void setPriority(void);
01336 
01341     static void yield(void);
01342 
01347     static void sleep(timeout_t timeout);
01348 
01355     static Thread *get(void);
01356 
01360     virtual void run(void) = 0;
01361 
01365     virtual ~Thread();
01366 
01375     virtual void exit(void);
01376 
01380     static void init(void);
01381 
01387     static void policy(int polid);
01388 
01393     static void concurrency(int level);
01394 
01401     static bool equal(pthread_t thread1, pthread_t thread2);
01402 
01407     static pthread_t self(void);
01408 
01409     inline operator bool() const
01410         {return is_active();}
01411 
01412     inline bool operator!() const
01413         {return !is_active();}
01414 
01415     inline bool isRunning(void) const
01416         {return is_active();}
01417 };
01418 
01429 class __EXPORT JoinableThread : public Thread
01430 {
01431 protected:
01432 #ifdef  _MSTHREADS_
01433     HANDLE running;
01434 #else
01435     volatile bool running;
01436 #endif
01437     volatile bool joining;
01438 
01443     JoinableThread(size_t size = 0);
01444 
01449     virtual ~JoinableThread();
01450 
01456     void join(void);
01457 
01458     bool is_active(void) const;
01459 
01460     virtual void run(void) = 0;
01461 
01462 public:
01463 
01472     void start(int priority = 0);
01473 
01478     inline void background(void)
01479         {start(-1);}
01480 };
01481 
01489 class __EXPORT DetachedThread : public Thread
01490 {
01491 protected:
01492     bool active;
01493 
01498     DetachedThread(size_t size = 0);
01499 
01505     ~DetachedThread();
01506 
01515     void exit(void);
01516 
01517     bool is_active(void) const;
01518 
01519     virtual void run(void) = 0;
01520 
01521 public:
01528     void start(int priority = 0);
01529 };
01530 
01539 class __EXPORT locked_release
01540 {
01541 protected:
01542     ObjectProtocol *object; 
01547     locked_release();
01548 
01554     locked_release(const locked_release &object);
01555 
01556 public:
01562     locked_release(LockedPointer &pointer);
01563 
01568     ~locked_release();
01569 
01573     void release(void);
01574 
01580     locked_release &operator=(LockedPointer &pointer);
01581 };
01582 
01592 class __EXPORT shared_release
01593 {
01594 protected:
01595     SharedPointer *ptr; 
01600     shared_release();
01601 
01607     shared_release(const shared_release &object);
01608 
01609 public:
01614     shared_release(SharedPointer &pointer);
01615 
01621     ~shared_release();
01622 
01626     void release(void);
01627 
01632     SharedObject *get(void);
01633 
01639     shared_release &operator=(SharedPointer &pointer);
01640 };
01641 
01649 template<class T>
01650 class shared_pointer : public SharedPointer
01651 {
01652 public:
01656     inline shared_pointer() : SharedPointer() {}
01657 
01665     inline const T *dup(void)
01666         {return static_cast<const T*>(SharedPointer::share());}
01667 
01674     inline void replace(T *object)
01675         {SharedPointer::replace(object);}
01676 
01681     inline void operator=(T *object)
01682         {replace(object);}
01683 
01688     inline T *operator*()
01689         {return dup();}
01690 };
01691 
01699 template<class T>
01700 class locked_pointer : public LockedPointer
01701 {
01702 public:
01706     inline locked_pointer() : LockedPointer() {}
01707 
01713     inline T* dup(void)
01714         {return static_cast<T *>(LockedPointer::dup());}
01715 
01720     inline void replace(T *object)
01721         {LockedPointer::replace(object);}
01722 
01727     inline void operator=(T *object)
01728         {replace(object);}
01729 
01735     inline T *operator*()
01736         {return dup();}
01737 };
01738 
01744 template<class T>
01745 class locked_instance : public locked_release
01746 {
01747 public:
01751     inline locked_instance() : locked_release() {}
01752 
01757     inline locked_instance(locked_pointer<T> &pointer) : locked_release(pointer) {}
01758 
01763     inline T& operator*() const
01764         {return *(static_cast<T&>(object));}
01765 
01770     inline T* operator->() const
01771         {return static_cast<T*>(object);}
01772 
01777     inline T* get(void) const
01778         {return static_cast<T*>(object);}
01779 };
01780 
01786 template<class T>
01787 class shared_instance : public shared_release
01788 {
01789 public:
01793     inline shared_instance() : shared_release() {}
01794 
01800     inline shared_instance(shared_pointer<T> &pointer) : shared_release(pointer) {}
01801 
01805     inline const T& operator*() const
01806         {return *(static_cast<const T&>(ptr->pointer));}
01807 
01812     inline const T* operator->() const
01813         {return static_cast<const T*>(ptr->pointer);}
01814 
01819     inline const T* get(void) const
01820         {return static_cast<const T*>(ptr->pointer);}
01821 };
01822 
01829 template <class T>
01830 class mutex_pointer : public auto_protect
01831 {
01832 public:
01836     inline mutex_pointer() : auto_protect() {}
01837 
01842     inline mutex_pointer(T* object) : auto_protect(object) {}
01843 
01848     inline T& operator*() const
01849         {return *(static_cast<T&>(auto_protect::object));}
01850 
01855     inline T* operator->() const
01856         {return static_cast<T*>(auto_protect::object);}
01857 
01862     inline T* get(void) const
01863         {return static_cast<T*>(auto_protect::object);}
01864 };
01865 
01871 inline void start(JoinableThread *thread, int priority = 0)
01872     {thread->start(priority);}
01873 
01879 inline void start(DetachedThread *thread, int priority = 0)
01880     {thread->start(priority);}
01881 
01885 typedef ConditionalLock condlock_t;
01886 
01890 typedef ConditionalAccess accesslock_t;
01891 
01895 typedef TimedEvent timedevent_t;
01896 
01900 typedef Mutex mutex_t;
01901 
01905 typedef ThreadLock rwlock_t;
01906 
01910 typedef RecursiveMutex rexlock_t;
01911 
01915 typedef Semaphore semaphore_t;
01916 
01920 typedef barrier barrier_t;
01921 
01926 inline void wait(barrier_t &barrier)
01927     {barrier.wait();}
01928 
01934 inline void wait(semaphore_t &semaphore, timeout_t timeout = Timer::inf)
01935     {semaphore.wait(timeout);}
01936 
01941 inline void release(semaphore_t &semaphore)
01942     {semaphore.release();}
01943 
01948 inline void acquire(mutex_t &mutex)
01949     {mutex.lock();}
01950 
01955 inline void release(mutex_t &mutex)
01956     {mutex.release();}
01957 
01962 inline void modify(accesslock_t &lock)
01963     {lock.modify();}
01964 
01969 inline void access(accesslock_t &lock)
01970     {lock.access();}
01971 
01976 inline void release(accesslock_t &lock)
01977     {lock.release();}
01978 
01984 inline void commit(accesslock_t &lock)
01985     {lock.commit();}
01986 
01991 inline void exclusive(condlock_t &lock)
01992     {lock.exclusive();}
01993 
01998 inline void share(condlock_t &lock)
01999     {lock.share();}
02000 
02005 inline void modify(condlock_t &lock)
02006     {lock.modify();}
02007 
02013 inline void commit(condlock_t &lock)
02014     {lock.commit();}
02015 
02020 inline void access(condlock_t &lock)
02021     {lock.access();}
02022 
02027 inline void release(condlock_t &lock)
02028     {lock.release();}
02029 
02035 inline bool exclusive(rwlock_t &lock, timeout_t timeout = Timer::inf)
02036     {return lock.modify(timeout);}
02037 
02043 inline bool share(rwlock_t &lock, timeout_t timeout = Timer::inf)
02044     {return lock.access(timeout);}
02045 
02050 inline void release(rwlock_t &lock)
02051     {lock.release();}
02052 
02057 inline void lock(rexlock_t &lock)
02058     {lock.lock();}
02059 
02064 inline void release(rexlock_t &lock)
02065     {lock.release();}
02066 
02067 #define __AUTOLOCK__    autolock __autolock__(this);
02068 
02069 #define __SYNC__ for(bool _sync_flag_ = Mutex::protect(this); _sync_flag_; _sync_flag_ = !Mutex::release(this))
02070 
02071 #define __SHARED__ for(bool _sync_flag_ = ThreadLock::reader(this); _sync_flag_; _sync_flag_ = !ThreadLock::release(this))
02072 
02073 #define ___EXCLUSIVE__ for(bool _sync_flag_ = ThreadLock::writer(this); _sync_flag_; _sync_flag_ = !ThreadLock::release(this))
02074 
02075 } // namespace ucommon
02076 
02077 #endif