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_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 void release(void); 00493 00498 unsigned getLocking(void); 00499 00504 unsigned getWaiting(void); 00505 00510 inline static void lock(rexlock& rex) 00511 {rex.lock();}; 00512 00517 inline static void release(rexlock& rex) 00518 {rex.release();}; 00519 }; 00520 00533 class __EXPORT rwlock : private ConditionalAccess, public Exclusive, public Shared 00534 { 00535 private: 00536 unsigned writers; 00537 pthread_t writeid; 00538 00539 __LOCAL void Exlock(void); 00540 __LOCAL void Shlock(void); 00541 __LOCAL void Unlock(void); 00542 00543 public: 00551 class __EXPORT gaurd_reader 00552 { 00553 private: 00554 void *object; 00555 00556 public: 00561 gaurd_reader(); 00562 00567 gaurd_reader(void *object); 00568 00572 ~gaurd_reader(); 00573 00579 void set(void *object); 00580 00584 void release(void); 00585 00591 inline void operator=(void *pointer) 00592 {set(pointer);}; 00593 }; 00594 00602 class __EXPORT gaurd_writer 00603 { 00604 private: 00605 void *object; 00606 00607 public: 00612 gaurd_writer(); 00613 00618 gaurd_writer(void *object); 00619 00623 ~gaurd_writer(); 00624 00630 void set(void *object); 00631 00635 void release(void); 00636 00642 inline void operator=(void *pointer) 00643 {set(pointer);}; 00644 }; 00645 00649 rwlock(); 00650 00656 bool modify(timeout_t timeout = Timer::inf); 00657 00663 bool access(timeout_t timeout = Timer::inf); 00664 00671 static void indexing(unsigned size); 00672 00680 static bool writer(void *object, timeout_t timeout = Timer::inf); 00681 00689 static bool reader(void *object, timeout_t timeout = Timer::inf); 00690 00695 static void release(void *object); 00696 00700 void release(void); 00701 00706 unsigned getAccess(void); 00707 00712 unsigned getModify(void); 00713 00718 unsigned getWaiting(void); 00719 00726 inline static bool modify(rwlock& lock, timeout_t timeout = Timer::inf) 00727 {return lock.modify(timeout);}; 00728 00735 inline static bool access(rwlock& lock, timeout_t timeout = Timer::inf) 00736 {return lock.access(timeout);}; 00737 00742 inline static void release(rwlock& lock) 00743 {lock.release();}; 00744 }; 00745 00756 class __EXPORT ReusableAllocator : protected Conditional 00757 { 00758 protected: 00759 ReusableObject *freelist; 00760 unsigned waiting; 00761 00765 ReusableAllocator(); 00766 00772 inline ReusableObject *next(ReusableObject *object) 00773 {return object->getNext();}; 00774 00779 void release(ReusableObject *object); 00780 }; 00781 00792 class __EXPORT ConditionalLock : protected ConditionalAccess, public Shared 00793 { 00794 private: 00795 class Context : public LinkedObject 00796 { 00797 public: 00798 inline Context(LinkedObject **root) : LinkedObject(root) {}; 00799 00800 pthread_t thread; 00801 unsigned count; 00802 }; 00803 00804 LinkedObject *contexts; 00805 00806 __LOCAL void Shlock(void); 00807 __LOCAL void Unlock(void); 00808 __LOCAL void Exclusive(void); 00809 __LOCAL void Share(void); 00810 __LOCAL Context *getContext(void); 00811 00812 public: 00816 ConditionalLock(); 00817 00821 ~ConditionalLock(); 00822 00826 void modify(void); 00827 00831 void commit(void); 00832 00836 void access(void); 00837 00841 void release(void); 00842 00847 void exclusive(void); 00848 00852 void share(void); 00853 00857 unsigned getReaders(void); 00858 00862 unsigned getWaiters(void); 00863 00868 inline static void modify(ConditionalLock& lock) 00869 {lock.modify();}; 00870 00875 inline static void commit(ConditionalLock& lock) 00876 {lock.commit();}; 00877 00882 inline static void release(ConditionalLock& lock) 00883 {lock.release();}; 00884 00889 inline static void access(ConditionalLock& lock) 00890 {lock.access();}; 00891 00896 inline static void exclusive(ConditionalLock& lock) 00897 {lock.exclusive();}; 00898 00903 inline static void share(ConditionalLock& lock) 00904 {lock.share();}; 00905 }; 00906 00919 class __EXPORT barrier : private Conditional 00920 { 00921 private: 00922 unsigned count; 00923 unsigned waits; 00924 00925 public: 00930 barrier(unsigned count); 00931 00935 ~barrier(); 00936 00942 void set(unsigned count); 00943 00947 void inc(void); 00948 00953 unsigned operator++(void); 00954 00958 void wait(void); 00959 00966 bool wait(timeout_t timeout); 00967 00972 inline static void wait(barrier& sync) 00973 {sync.wait();}; 00974 00981 inline static bool wait(barrier& sync, timeout_t timeout) 00982 {return sync.wait(timeout);}; 00983 00984 00990 inline static void set(barrier& sync, unsigned count) 00991 {sync.set(count);}; 00992 }; 00993 01002 class __EXPORT semaphore : public Shared, private Conditional 01003 { 01004 private: 01005 unsigned count, waits, used; 01006 01007 __LOCAL void Shlock(void); 01008 __LOCAL void Unlock(void); 01009 01010 public: 01014 semaphore(unsigned count = 0); 01015 01020 void wait(void); 01021 01029 bool wait(timeout_t timeout); 01030 01035 unsigned getCount(void); 01036 01041 unsigned getUsed(void); 01042 01047 void set(unsigned count); 01048 01052 void release(void); 01053 01057 inline void operator++(void) 01058 {wait();}; 01059 01063 inline void operator--(void) 01064 {release();}; 01065 01070 inline static void wait(semaphore& sync) 01071 {sync.wait();}; 01072 01079 inline static bool wait(semaphore& sync, timeout_t timeout) 01080 {return sync.wait(timeout);}; 01081 01086 inline static void release(semaphore& sync) 01087 {sync.release();}; 01088 }; 01089 01103 class __EXPORT mutex : public Exclusive 01104 { 01105 private: 01106 pthread_mutex_t mlock; 01107 01108 __LOCAL void Exlock(void); 01109 __LOCAL void Unlock(void); 01110 01111 public: 01119 class __EXPORT gaurd 01120 { 01121 private: 01122 void *object; 01123 01124 public: 01129 gaurd(); 01130 01135 gaurd(void *object); 01136 01140 ~gaurd(); 01141 01147 void set(void *object); 01148 01152 void release(void); 01153 01159 inline void operator=(void *pointer) 01160 {set(pointer);}; 01161 }; 01162 01163 01167 mutex(); 01168 01172 ~mutex(); 01173 01177 inline void acquire(void) 01178 {pthread_mutex_lock(&mlock);}; 01179 01183 inline void lock(void) 01184 {pthread_mutex_lock(&mlock);}; 01185 01189 inline void unlock(void) 01190 {pthread_mutex_unlock(&mlock);}; 01191 01195 inline void release(void) 01196 {pthread_mutex_unlock(&mlock);}; 01197 01202 inline static void acquire(mutex& lock) 01203 {pthread_mutex_lock(&lock.mlock);}; 01204 01209 inline static void lock(mutex& lock) 01210 {pthread_mutex_lock(&lock.mlock);}; 01211 01216 inline static void unlock(mutex& lock) 01217 {pthread_mutex_unlock(&lock.mlock);}; 01218 01223 inline static void release(mutex& lock) 01224 {pthread_mutex_unlock(&lock.mlock);}; 01225 01230 inline static void acquire(pthread_mutex_t *lock) 01231 {pthread_mutex_lock(lock);}; 01232 01237 inline static void lock(pthread_mutex_t *lock) 01238 {pthread_mutex_lock(lock);}; 01239 01244 inline static void unlock(pthread_mutex_t *lock) 01245 {pthread_mutex_unlock(lock);}; 01246 01251 inline static void release(pthread_mutex_t *lock) 01252 {pthread_mutex_unlock(lock);}; 01253 01260 static void indexing(unsigned size); 01261 01267 static void protect(void *pointer); 01268 01273 static void release(void *pointer); 01274 }; 01275 01284 class __EXPORT auto_protect 01285 { 01286 private: 01287 // cannot copy... 01288 inline auto_protect(const auto_pointer &pointer) {}; 01289 01290 protected: 01291 void *object; 01292 01293 auto_protect(); 01294 01295 public: 01300 auto_protect(void *object); 01301 01306 ~auto_protect(); 01307 01311 void release(void); 01312 01317 inline bool operator!() const 01318 {return object == NULL;}; 01319 01324 inline operator bool() const 01325 {return object != NULL;}; 01326 01333 void operator=(void *object); 01334 }; 01335 01347 class __EXPORT LockedPointer 01348 { 01349 private: 01350 friend class locked_release; 01351 pthread_mutex_t mutex; 01352 Object *pointer; 01353 01354 protected: 01358 LockedPointer(); 01359 01364 void replace(Object *object); 01365 01370 Object *dup(void); 01371 01376 inline void operator=(Object *object) 01377 {replace(object);}; 01378 }; 01379 01388 class __EXPORT SharedObject 01389 { 01390 protected: 01391 friend class SharedPointer; 01392 01401 virtual void commit(SharedPointer *pointer); 01402 01403 public: 01407 virtual ~SharedObject(); 01408 }; 01409 01420 class __EXPORT SharedPointer : protected ConditionalAccess 01421 { 01422 private: 01423 friend class shared_release; 01424 SharedObject *pointer; 01425 01426 protected: 01430 SharedPointer(); 01431 01435 ~SharedPointer(); 01436 01443 void replace(SharedObject *object); 01444 01451 SharedObject *share(void); 01452 }; 01453 01464 class __EXPORT Thread 01465 { 01466 protected: 01467 pthread_t tid; 01468 size_t stack; 01469 int priority; 01470 01476 Thread(size_t stack = 0); 01477 01478 public: 01485 void setPriority(void); 01486 01491 static void yield(void); 01492 01497 static void sleep(timeout_t timeout); 01498 01502 virtual void run(void) = 0; 01503 01507 virtual ~Thread(); 01508 01517 virtual void exit(void); 01518 01522 static void init(void); 01523 01529 static void policy(int polid); 01530 01535 static void concurrency(int level); 01536 01543 static bool equal(pthread_t thread1, pthread_t thread2); 01544 01549 #ifdef __PTH__ 01550 inline static pthread_t self(void) 01551 {return pth_self();}; 01552 #else 01553 inline static pthread_t self(void) 01554 {return pthread_self();}; 01555 #endif 01556 }; 01557 01568 class __EXPORT JoinableThread : protected Thread 01569 { 01570 private: 01571 #ifdef _MSWINDOWS_ 01572 HANDLE joining; 01573 #else 01574 volatile bool running; 01575 #endif 01576 01577 protected: 01582 JoinableThread(size_t size = 0); 01583 01588 virtual ~JoinableThread(); 01589 01595 void join(void); 01596 01597 public: 01598 #ifdef _MSWINDOWS_ 01599 inline bool isRunning(void) 01600 {return (joining != INVALID_HANDLE_VALUE);}; 01601 #else 01602 01606 inline bool isRunning(void) 01607 {return running;}; 01608 #endif 01609 01618 void start(int priority = 0); 01619 01624 inline void background(void) 01625 {start(-1);}; 01626 }; 01627 01635 class __EXPORT DetachedThread : protected Thread 01636 { 01637 protected: 01642 DetachedThread(size_t size = 0); 01643 01649 ~DetachedThread(); 01650 01659 void exit(void); 01660 01661 public: 01668 void start(int priority = 0); 01669 }; 01670 01681 class __EXPORT queue : protected OrderedIndex, protected Conditional 01682 { 01683 private: 01684 mempager *pager; 01685 LinkedObject *freelist; 01686 size_t used; 01687 01688 class __LOCAL member : public OrderedObject 01689 { 01690 public: 01691 member(queue *q, Object *obj); 01692 Object *object; 01693 }; 01694 01695 friend class member; 01696 01697 protected: 01698 size_t limit; 01699 01700 public: 01708 queue(mempager *pager = NULL, size_t number = 0); 01709 01713 ~queue(); 01714 01722 bool remove(Object *object); 01723 01732 bool post(Object *object, timeout_t timeout = 0); 01733 01741 Object *fifo(timeout_t timeout = 0); 01742 01750 Object *lifo(timeout_t timeout = 0); 01751 01756 size_t getCount(void); 01757 01764 static bool remove(queue& queue, Object *object) 01765 {return queue.remove(object);}; 01766 01774 static bool post(queue& queue, Object *object, timeout_t timeout = 0) 01775 {return queue.post(object, timeout);}; 01776 01783 static Object *fifo(queue& queue, timeout_t timeout = 0) 01784 {return queue.fifo(timeout);}; 01785 01792 static Object *lifo(queue& queue, timeout_t timeout = 0) 01793 {return queue.lifo(timeout);}; 01794 01800 static size_t count(queue& queue) 01801 {return queue.getCount();}; 01802 }; 01803 01812 class __EXPORT stack : protected Conditional 01813 { 01814 private: 01815 LinkedObject *freelist, *usedlist; 01816 mempager *pager; 01817 size_t used; 01818 01819 class __LOCAL member : public LinkedObject 01820 { 01821 public: 01822 member(stack *s, Object *obj); 01823 Object *object; 01824 }; 01825 01826 friend class member; 01827 01828 protected: 01829 size_t limit; 01830 01831 public: 01838 stack(mempager *pager = NULL, size_t number = 0); 01839 01843 ~stack(); 01844 01852 bool remove(Object *object); 01853 01862 bool push(Object *object, timeout_t timeout = 0); 01863 01871 Object *pull(timeout_t timeout = 0); 01872 01877 size_t getCount(void); 01878 01885 static inline bool remove(stack& stack, Object *object) 01886 {return stack.remove(object);}; 01887 01895 static inline bool push(stack& stack, Object *object, timeout_t timeout = 0) 01896 {return stack.push(object, timeout);}; 01897 01904 static inline Object *pull(stack& stack, timeout_t timeout = 0) 01905 {return stack.pull(timeout);}; 01906 01912 static inline size_t count(stack& stack) 01913 {return stack.getCount();}; 01914 }; 01915 01925 class __EXPORT Buffer : protected Conditional 01926 { 01927 private: 01928 size_t size, objsize; 01929 caddr_t buf, head, tail; 01930 unsigned count, limit; 01931 01932 public: 01938 Buffer(size_t size, size_t count); 01939 01943 virtual ~Buffer(); 01944 01949 unsigned getSize(void); 01950 01955 unsigned getCount(void); 01956 01962 void *get(timeout_t timeout); 01963 01969 void *get(void); 01970 01976 void put(void *data); 01977 01984 bool put(void *data, timeout_t timeout); 01985 01992 void release(void); 01993 01999 void copy(void *data); 02000 02007 bool copy(void *data, timeout_t timeout); 02008 02013 operator bool(); 02014 02019 bool operator!(); 02020 }; 02021 02030 class __EXPORT locked_release 02031 { 02032 protected: 02033 Object *object; 02038 locked_release(); 02039 02045 locked_release(const locked_release &object); 02046 02047 public: 02053 locked_release(LockedPointer &pointer); 02054 02059 ~locked_release(); 02060 02064 void release(void); 02065 02071 locked_release &operator=(LockedPointer &pointer); 02072 }; 02073 02083 class __EXPORT shared_release 02084 { 02085 protected: 02086 SharedPointer *ptr; 02091 shared_release(); 02092 02098 shared_release(const shared_release &object); 02099 02100 public: 02105 shared_release(SharedPointer &pointer); 02106 02112 ~shared_release(); 02113 02117 void release(void); 02118 02123 SharedObject *get(void); 02124 02130 shared_release &operator=(SharedPointer &pointer); 02131 }; 02132 02140 template<class T> 02141 class queueof : public queue 02142 { 02143 public: 02149 inline queueof(mempager *memory, size_t size = 0) : queue(memory, size) {}; 02150 02158 inline bool remove(T *object) 02159 {return queue::remove(object);}; 02160 02169 inline bool post(T *object, timeout_t timeout = 0) 02170 {return queue::post(object);}; 02171 02179 inline T *fifo(timeout_t timeout = 0) 02180 {return static_cast<T *>(queue::fifo(timeout));}; 02181 02189 inline T *lifo(timeout_t timeout = 0) 02190 {return static_cast<T *>(queue::lifo(timeout));}; 02191 }; 02192 02200 template<class T> 02201 class stackof : public stack 02202 { 02203 public: 02209 inline stackof(mempager *memory, size_t size = 0) : stack(memory, size) {}; 02210 02218 inline bool remove(T *object) 02219 {return stack::remove(object);}; 02220 02229 inline bool push(T *object, timeout_t timeout = 0) 02230 {return stack::push(object);}; 02231 02239 inline T *pull(timeout_t timeout = 0) 02240 {return static_cast<T *>(stack::pull(timeout));}; 02241 }; 02242 02254 template<class T> 02255 class bufferof : public Buffer 02256 { 02257 public: 02262 inline bufferof(unsigned count) : 02263 Buffer(sizeof(T), count) {}; 02264 02270 inline T *get(void) 02271 {return static_cast<T*>(get());}; 02272 02278 inline T *get(timeout_t timeout) 02279 {return static_cast<T*>(get(timeout));}; 02280 02286 inline void put(T *object) 02287 {put(object);}; 02288 02295 inline bool put(T *object, timeout_t timeout) 02296 {return put(object, timeout);}; 02297 02303 inline void copy(T *object) 02304 {copy(object);}; 02305 02312 inline bool get(T *object, timeout_t timeout) 02313 {return copy(object, timeout);}; 02314 }; 02315 02323 template<class T> 02324 class shared_pointer : public SharedPointer 02325 { 02326 public: 02330 inline shared_pointer() : SharedPointer() {}; 02331 02339 inline const T *dup(void) 02340 {return static_cast<const T*>(SharedPointer::share());}; 02341 02348 inline void replace(T *object) 02349 {SharedPointer::replace(object);}; 02350 02355 inline void operator=(T *object) 02356 {replace(object);}; 02357 02362 inline T *operator*() 02363 {return dup();}; 02364 }; 02365 02373 template<class T> 02374 class locked_pointer : public LockedPointer 02375 { 02376 public: 02380 inline locked_pointer() : LockedPointer() {}; 02381 02387 inline T* dup(void) 02388 {return static_cast<T *>(LockedPointer::dup());}; 02389 02394 inline void replace(T *object) 02395 {LockedPointer::replace(object);}; 02396 02401 inline void operator=(T *object) 02402 {replace(object);}; 02403 02409 inline T *operator*() 02410 {return dup();}; 02411 }; 02412 02418 template<class T> 02419 class locked_instance : public locked_release 02420 { 02421 public: 02425 inline locked_instance() : locked_release() {}; 02426 02431 inline locked_instance(locked_pointer<T> &pointer) : locked_release(pointer) {}; 02432 02437 inline T& operator*() const 02438 {return *(static_cast<T *>(object));}; 02439 02444 inline T* operator->() const 02445 {return static_cast<T*>(object);}; 02446 02451 inline T* get(void) const 02452 {return static_cast<T*>(object);}; 02453 }; 02454 02460 template<class T> 02461 class shared_instance : public shared_release 02462 { 02463 public: 02467 inline shared_instance() : shared_release() {}; 02468 02474 inline shared_instance(shared_pointer<T> &pointer) : shared_release(pointer) {}; 02475 02479 inline const T& operator*() const 02480 {return *(static_cast<const T *>(ptr->pointer));}; 02481 02486 inline const T* operator->() const 02487 {return static_cast<const T*>(ptr->pointer);}; 02488 02493 inline const T* get(void) const 02494 {return static_cast<const T*>(ptr->pointer);}; 02495 }; 02496 02503 template <class T> 02504 class mutex_pointer : public auto_protect 02505 { 02506 public: 02510 inline mutex_pointer() : auto_protect() {}; 02511 02516 inline mutex_pointer(T* object) : auto_protect(object) {}; 02517 02522 inline T& operator*() const 02523 {return *(static_cast<T*>(auto_protect::object));}; 02524 02529 inline T* operator->() const 02530 {return static_cast<T*>(auto_protect::object);}; 02531 02536 inline T* get(void) const 02537 {return static_cast<T*>(auto_protect::object);}; 02538 }; 02539 02545 inline void start(JoinableThread *thread, int priority = 0) 02546 {thread->start(priority);} 02547 02553 inline void start(DetachedThread *thread, int priority = 0) 02554 {thread->start(priority);} 02555 02559 typedef ConditionalLock condlock_t; 02560 02564 typedef ConditionalAccess accesslock_t; 02565 02569 typedef TimedEvent timedevent_t; 02570 02574 typedef mutex mutex_t; 02575 02580 typedef mutex Mutex; 02581 02585 typedef rwlock rwlock_t; 02586 02590 typedef rexlock rexlock_t; 02591 02595 typedef semaphore semaphore_t; 02596 02600 typedef barrier barrier_t; 02601 02605 typedef stack stack_t; 02606 02610 typedef queue fifo_t; 02611 02616 inline void wait(barrier_t &barrier) 02617 {barrier.wait();} 02618 02624 inline void wait(semaphore_t &semaphore, timeout_t timeout = Timer::inf) 02625 {semaphore.wait(timeout);} 02626 02631 inline void release(semaphore_t &semaphore) 02632 {semaphore.release();} 02633 02638 inline void acquire(mutex_t &mutex) 02639 {mutex.lock();} 02640 02645 inline void release(mutex_t &mutex) 02646 {mutex.release();} 02647 02652 inline void modify(accesslock_t &lock) 02653 {lock.modify();} 02654 02659 inline void access(accesslock_t &lock) 02660 {lock.access();} 02661 02666 inline void release(accesslock_t &lock) 02667 {lock.release();} 02668 02674 inline void commit(accesslock_t &lock) 02675 {lock.commit();} 02676 02681 inline void exclusive(condlock_t &lock) 02682 {lock.exclusive();} 02683 02688 inline void share(condlock_t &lock) 02689 {lock.share();} 02690 02695 inline void modify(condlock_t &lock) 02696 {lock.modify();} 02697 02703 inline void commit(condlock_t &lock) 02704 {lock.commit();} 02705 02710 inline void access(condlock_t &lock) 02711 {lock.access();} 02712 02717 inline void release(condlock_t &lock) 02718 {lock.release();} 02719 02725 inline bool exclusive(rwlock_t &lock, timeout_t timeout = Timer::inf) 02726 {return lock.modify(timeout);} 02727 02733 inline bool share(rwlock_t &lock, timeout_t timeout = Timer::inf) 02734 {return lock.access(timeout);} 02735 02740 inline void release(rwlock_t &lock) 02741 {lock.release();} 02742 02747 inline void lock(rexlock_t &lock) 02748 {lock.lock();} 02749 02754 inline void release(rexlock_t &lock) 02755 {lock.release();} 02756 02762 inline void push(stack_t &stack, Object *object) 02763 {stack.push(object);} 02764 02771 inline Object *pull(stack_t &stack, timeout_t timeout = Timer::inf) 02772 {return stack.pull(timeout);} 02773 02779 inline void remove(stack_t &stack, Object *object) 02780 {stack.remove(object);} 02781 02787 inline void push(fifo_t &fifo, Object *object) 02788 {fifo.post(object);} 02789 02796 inline Object *pull(fifo_t &fifo, timeout_t timeout = Timer::inf) 02797 {return fifo.fifo(timeout);} 02798 02804 inline void remove(fifo_t &fifo, Object *object) 02805 {fifo.remove(object);} 02806 02807 END_NAMESPACE 02808 02809 #define ENTER_EXCLUSIVE \ 02810 do { static pthread_mutex_t __sync__ = PTHREAD_MUTEX_INITIALIZER; \ 02811 pthread_mutex_lock(&__sync__); 02812 02813 #define LEAVE_EXCLUSIVE \ 02814 pthread_mutex_unlock(&__sync__);} while(0); 02815 02816 #endif