00001
00011 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
00012 #pragma once
00013 #endif
00014 #ifndef COMMON_THREADS_H_
00015 #define COMMON_THREADS_H_
00016
00017 namespace common
00018 {
00019
00024
00026 class Thread_pimpl;
00028 class Mutex_pimpl;
00030 class Semaphore_pimpl;
00032 class Cond_pimpl;
00034 class Barrier_pimpl;
00036 class Event_pimpl;
00037
00039
00047 class Thread
00048 {
00049 DECLARE_NO_COPY_CLASS(Thread)
00050 friend class Thread_pimpl;
00051
00052 private:
00053 scoped_ptr<Thread_pimpl> pimpl;
00054
00055 protected:
00057 virtual void Run() = 0;
00058
00060
00065 void Exit();
00067
00071 void Yield_();
00072
00073 public:
00074 Thread();
00075 virtual ~Thread();
00076
00078 void Start();
00080
00084 void Join();
00085
00087 void Kill();
00088
00089
00090 #ifdef WIN32
00091 uint GetNativeHandle();
00092 uint GetNativeId();
00093
00094 bool IsRunning();
00096
00100 void Pause();
00101 void Resume();
00102
00107 static const int PRIORITY_IDLE;
00108 static const int PRIORITY_VERY_LOW;
00109 static const int PRIORITY_LOW;
00110 static const int PRIORITY_DEFAULT;
00111 static const int PRIORITY_HIGH;
00112 static const int PRIORITY_VERY_HIGH;
00113 static const int PRIORITY_REALTIME;
00114 void SetPriority(int Priority);
00115 int GetPriority();
00116
00117 void SetThreadName(const char *s);
00118 static void SetThreadNameById(uint threadId, const char *s);
00119 static void SetMainThreadName(const char *s);
00121 #endif
00122 };
00123
00125
00128 class Mutex
00129 {
00130 DECLARE_NO_COPY_CLASS(Mutex)
00131 friend class Mutex_pimpl;
00132 friend class Cond;
00133
00134 private:
00135 scoped_ptr<Mutex_pimpl> pimpl;
00136
00137 public:
00140
00141 static const uint FLAG_RECURSIVE = 0x01;
00143 static const uint FLAG_WAIT_TIMEOUT = 0x02;
00145
00146 Mutex(uint Flag);
00147 ~Mutex();
00148
00150 void Lock();
00152 void Unlock();
00154
00158 bool TryLock();
00160
00164 bool TimeoutLock(uint Milliseconds);
00165 };
00166
00168
00172 class MutexLock
00173 {
00174 private:
00175 Mutex &m_Mutex;
00176 DECLARE_NO_COPY_CLASS(MutexLock)
00177
00178 public:
00179 MutexLock(Mutex &m) : m_Mutex(m) { m.Lock(); }
00180 ~MutexLock() { m_Mutex.Unlock(); }
00181 };
00182
00188 #define MUTEX_LOCK(M) common::MutexLock __mutex_lock_obj(M);
00189
00191
00196 class Semaphore
00197 {
00198 DECLARE_NO_COPY_CLASS(Semaphore)
00199
00200 private:
00201 scoped_ptr<Semaphore_pimpl> pimpl;
00202
00203 public:
00204 Semaphore(uint InitialValue);
00205 ~Semaphore();
00206
00208
00211 void P();
00213
00217 bool TryP();
00219
00223 bool TimeoutP(uint Milliseconds);
00224
00226 void V();
00228 void V(uint ReleaseCount);
00229 };
00230
00232
00238 class Cond
00239 {
00240 DECLARE_NO_COPY_CLASS(Cond)
00241
00242 private:
00243 scoped_ptr<Cond_pimpl> pimpl;
00244
00245 public:
00246 Cond();
00247 ~Cond();
00248
00250
00251 void Wait(Mutex *m);
00253
00257 bool TimeoutWait(Mutex *m, uint Milliseconds);
00258
00260
00264 void Signal();
00266
00270 void Broadcast();
00271 };
00272
00274
00279 class Barrier
00280 {
00281 DECLARE_NO_COPY_CLASS(Barrier)
00282
00283 private:
00284 scoped_ptr<Barrier_pimpl> pimpl;
00285
00286 public:
00287 Barrier(uint NumThreads);
00288 ~Barrier();
00289
00290 void Wait();
00291 };
00292
00294
00298 class Event
00299 {
00300 DECLARE_NO_COPY_CLASS(Event);
00301
00302 private:
00303 scoped_ptr<Event_pimpl> pimpl;
00304
00305 public:
00306 enum TYPE
00307 {
00310 TYPE_AUTO_RESET,
00313 TYPE_MANUAL_RESET,
00314 };
00315
00316 Event(bool InitialState, TYPE Type);
00317 ~Event();
00318
00320
00324 void Set();
00326 void Reset();
00327
00329
00333 void Wait();
00335
00336 bool Test();
00338
00343 bool TimeoutWait(uint Milliseconds);
00344 };
00345
00346 class RWLock
00347 {
00348 DECLARE_NO_COPY_CLASS(RWLock)
00349
00350 public:
00351 RWLock() : m_Readers(0), m_ReadersEvent(true, Event::TYPE_AUTO_RESET), m_DataEvent(true, Event::TYPE_AUTO_RESET) { }
00352
00353 void LockWrite() { m_DataEvent.Wait(); }
00354 bool TryLockWrite() { return m_DataEvent.Test(); }
00355 bool TimeoutLockWrite(uint Milliseconds) { return m_DataEvent.TimeoutWait(Milliseconds); }
00356 void UnlockWrite() { m_DataEvent.Set(); }
00357
00358 void LockRead()
00359 {
00360 m_ReadersEvent.Wait();
00361 if (m_Readers++ == 0) m_DataEvent.Wait();
00362 m_ReadersEvent.Set();
00363 }
00364 void UnlockRead()
00365 {
00366 m_ReadersEvent.Wait();
00367 if (--m_Readers == 0) m_DataEvent.Set();
00368 m_ReadersEvent.Set();
00369 }
00370
00371 private:
00372 int m_Readers;
00373 Event m_ReadersEvent, m_DataEvent;
00374 };
00375
00376 class ReadLock
00377 {
00378 DECLARE_NO_COPY_CLASS(ReadLock)
00379 public:
00380 ReadLock(RWLock &lock) : m_Lock(lock) { lock.LockRead(); }
00381 ~ReadLock() { m_Lock.UnlockRead(); }
00382 private:
00383 RWLock &m_Lock;
00384 };
00385
00386 class WriteLock
00387 {
00388 DECLARE_NO_COPY_CLASS(WriteLock)
00389 public:
00390 WriteLock(RWLock &lock) : m_Lock(lock) { lock.LockWrite(); }
00391 ~WriteLock() { m_Lock.UnlockWrite(); }
00392 private:
00393 RWLock &m_Lock;
00394 };
00395
00397
00398
00399 }
00400
00401 #endif