00001 00002 #ifndef L1394_THREAD_HPP 00003 #define L1394_THREAD_HPP 00004 00005 #include <pthread.h> 00006 namespace L1394 { 00007 class ThreadCondition; 00008 00009 /** This class is a wrapper for the pthread_mutex variables. 00010 */ 00011 class ThreadMutex { 00012 /*Define ThreadCondiotion as friend. So it can access <mutex>*/ 00013 friend class ThreadCondition; 00014 public: 00015 enum MutexKind {FAST, RECURSIVE}; 00016 00017 /** Constructor 00018 * \param MutexKind : This parameter determines whether a ThreadMutex can be 00019 * locked again by a thread that already owns it (Recursive) or not (Fast). 00020 * Default value is Fast. 00021 */ 00022 ThreadMutex(MutexKind mutex_kind = FAST); 00023 00024 /** Destructor 00025 */ 00026 ~ThreadMutex(); 00027 00028 /** This method locks the mutex. If the mutex is currently unlocked, it becomes locked 00029 * and owned by the calling thread. If the mutex is already locked by 00030 * another thread, the mutex suspends the calling thread until the mutex is unlocked. 00031 * If the MutexKind is 'Recursive' and the current thread locks again, a counter 00032 * is increased. 00033 */ 00034 void lock() const; 00035 00036 /** This method unlocks the mutex. If the MutexKind 'Fast', unlock 00037 * releases the mutex. If MutexKind is 'Recursive', it 00038 * decrements the locking count of the mutex and only when this 00039 * count reaches zero the mutex is released. 00040 */ 00041 void unlock() const; 00042 00043 /** This method differs form lock, that this method returns imediatly. 00044 * Return value is FAILURE if the mutex is already locked by another thread 00045 * else SUCCESS 00046 */ 00047 int tryLock() const; 00048 00049 private: 00050 00051 ThreadMutex(const ThreadMutex&); //disabled copy-constructor 00052 void operator=(const ThreadMutex&); //disabled assignement operator 00053 00054 mutable int lock_counter; 00055 MutexKind mutex_kind; 00056 mutable pthread_mutex_t mutex; 00057 mutable pthread_t current_thread; 00058 }; 00059 00060 00061 /** This class can be used to ensure that a locked mutex is unlocked if 00062 * you leave the scope 00063 */ 00064 class MutexGuard { 00065 public: 00066 /** Constructor 00067 * Locks the mutex 00068 */ 00069 MutexGuard(const ThreadMutex& mutex) : mutex(mutex) { is_owner = false; lock(); } 00070 00071 /** Destructor 00072 * Unlocks the Mutex, if it is not unlocked before 00073 */ 00074 ~MutexGuard() {mutex.unlock();} 00075 00076 /** This method unlocks the Mutex, if this MutexGuard is the owner 00077 */ 00078 void unlock() const { if (is_owner) { mutex.unlock(); is_owner = false; } } 00079 00080 /** This method locks the mutex and sets. 00081 */ 00082 void lock() const { is_owner = true; mutex.lock(); } 00083 private: 00084 const ThreadMutex& mutex; 00085 mutable bool is_owner; 00086 }; 00087 00088 /** This class is a wrapper for the pthread_cond_t variables. 00089 */ 00090 class ThreadCondition { 00091 public: 00092 00093 /** Constructor 00094 */ 00095 ThreadCondition(const ThreadMutex&); 00096 00097 /** Destructor 00098 */ 00099 ~ThreadCondition(); 00100 00101 /** timedWait atomically unlocks mutex and waits, but it also bounds the 00102 * duration of the wait. If notify has not been signaled within 00103 * the amount of time specified by abstime, the mutex is re-acquired. 00104 */ 00105 int timedWait(long sec = 0, long nsec = 0) const; 00106 00107 /** wait atomically unlocks the mutex and waits for the condition variable 00108 * to be signaled. 00109 */ 00110 void wait() const ; 00111 00112 /** Restarts one of the threads that are waiting on this condition variable. 00113 * If several threads are waiting, exactly one is restarted, but it is not 00114 * specified which. 00115 */ 00116 inline void notify() const {pthread_cond_signal(&cond);} 00117 00118 /** Restarts all the threads that are waiting on the condition variable. 00119 */ 00120 inline void notifyAll() const {pthread_cond_broadcast(&cond);} 00121 private: 00122 ThreadCondition(const ThreadCondition&); //disabled copy contructor 00123 void operator=(const ThreadCondition&); //disabled assignement operator 00124 00125 mutable pthread_cond_t cond; 00126 const ThreadMutex& mutex; 00127 }; 00128 00129 00130 /** This class is a wrapper for a pthread-threads. 00131 */ 00132 class Thread { 00133 public: 00134 typedef void* (*ThrFunction) (void*); 00135 /** Constructor 00136 */ 00137 Thread(); 00138 00139 /** Destructor 00140 */ 00141 ~Thread(); 00142 00143 /** Creates a new thread. 00144 * The new thread applies the function start_routine passing it arg as first 00145 * argument. The new thread terminates either explicitly, * 00146 * \param start_routine : pointer to the start_routine with type void* method(void*) 00147 * \param args : argument for the start_routine 00148 * \param attr : pthread attributes(see pthread manual) 00149 */ 00150 void start(ThrFunction start_routine, void *arg, pthread_attr_t* attr = 0 ); 00151 00152 00153 /** Kills the thread. 00154 */ 00155 void kill(); 00156 00157 /** Blocks until the thread terminates 00158 */ 00159 int join(); 00160 00161 /** Terminates the execution of the thread 00162 */ 00163 inline void exit() { pthread_exit(&thread); } 00164 00165 /** returns the ThreadID 00166 */ 00167 inline pthread_t getID() { return thread; } 00168 00169 private: 00170 pthread_t thread; 00171 00172 }; 00173 } 00174 #endif 00175