annotate thread/Thread.h @ 287:f857c6e81833

* oops... add thread abstraction
author Chris Cannam <c.cannam@qmul.ac.uk>
date Tue, 12 May 2009 17:56:58 +0000
parents
children 0dcbce5d7dce
rev   line source
c@287 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
c@287 2
c@287 3 /*
c@287 4 QM DSP Library
c@287 5
c@287 6 Centre for Digital Music, Queen Mary, University of London.
c@287 7 This file copyright Chris Cannam, used with permission.
c@287 8 */
c@287 9
c@287 10 #ifndef _THREAD_H_
c@287 11 #define _THREAD_H_
c@287 12
c@287 13 #ifdef _WIN32
c@287 14 #include <windows.h>
c@287 15 #else /* !_WIN32 */
c@287 16 #ifdef USE_PTHREADS
c@287 17 #include <pthread.h>
c@287 18 #endif /* USE_PTHREADS */
c@287 19 #endif /* !_WIN32 */
c@287 20
c@287 21 #include <string>
c@287 22
c@287 23 //#define DEBUG_THREAD 1
c@287 24 //#define DEBUG_MUTEX 1
c@287 25 //#define DEBUG_CONDITION 1
c@287 26
c@287 27 class Thread
c@287 28 {
c@287 29 public:
c@287 30 #ifdef _WIN32
c@287 31 typedef HANDLE Id;
c@287 32 #else
c@287 33 #ifdef USE_PTHREADS
c@287 34 typedef pthread_t Id;
c@287 35 #endif
c@287 36 #endif
c@287 37
c@287 38 Thread();
c@287 39 virtual ~Thread();
c@287 40
c@287 41 Id id();
c@287 42
c@287 43 void start();
c@287 44 void wait();
c@287 45
c@287 46 static bool threadingAvailable();
c@287 47
c@287 48 protected:
c@287 49 virtual void run() = 0;
c@287 50
c@287 51 private:
c@287 52 #ifdef _WIN32
c@287 53 HANDLE m_id;
c@287 54 bool m_extant;
c@287 55 static DWORD WINAPI staticRun(LPVOID lpParam);
c@287 56 #else
c@287 57 #ifdef USE_PTHREADS
c@287 58 pthread_t m_id;
c@287 59 bool m_extant;
c@287 60 static void *staticRun(void *);
c@287 61 #endif
c@287 62 #endif
c@287 63 };
c@287 64
c@287 65 class Mutex
c@287 66 {
c@287 67 public:
c@287 68 Mutex();
c@287 69 ~Mutex();
c@287 70
c@287 71 void lock();
c@287 72 void unlock();
c@287 73 bool trylock();
c@287 74
c@287 75 private:
c@287 76 #ifdef _WIN32
c@287 77 HANDLE m_mutex;
c@287 78 #ifndef NO_THREAD_CHECKS
c@287 79 DWORD m_lockedBy;
c@287 80 #endif
c@287 81 #else
c@287 82 #ifdef USE_PTHREADS
c@287 83 pthread_mutex_t m_mutex;
c@287 84 #ifndef NO_THREAD_CHECKS
c@287 85 pthread_t m_lockedBy;
c@287 86 bool m_locked;
c@287 87 #endif
c@287 88 #endif
c@287 89 #endif
c@287 90 };
c@287 91
c@287 92 class MutexLocker
c@287 93 {
c@287 94 public:
c@287 95 MutexLocker(Mutex *);
c@287 96 ~MutexLocker();
c@287 97
c@287 98 private:
c@287 99 Mutex *m_mutex;
c@287 100 };
c@287 101
c@287 102 class Condition
c@287 103 {
c@287 104 public:
c@287 105 Condition(std::string name);
c@287 106 ~Condition();
c@287 107
c@287 108 //!!! NO -- reproducing more conventional lock/wait
c@287 109
c@287 110 // To wait on a condition, either simply call wait(), or call
c@287 111 // lock() and then wait() (perhaps testing some state in between).
c@287 112 // To signal a condition, call signal().
c@287 113
c@287 114 // Although any thread may signal on a given condition, only one
c@287 115 // thread should ever wait on any given condition object --
c@287 116 // otherwise there will be a race conditions in the logic that
c@287 117 // avoids the thread code having to track whether the condition's
c@287 118 // mutex is locked or not. If that is your requirement, this
c@287 119 // Condition wrapper is not for you.
c@287 120 void lock();
c@287 121 void unlock();
c@287 122 void wait(int us = 0);
c@287 123
c@287 124 void signal();
c@287 125
c@287 126 private:
c@287 127
c@287 128 #ifdef _WIN32
c@287 129 HANDLE m_mutex;
c@287 130 HANDLE m_condition;
c@287 131 bool m_locked;
c@287 132 #else
c@287 133 #ifdef USE_PTHREADS
c@287 134 pthread_mutex_t m_mutex;
c@287 135 pthread_cond_t m_condition;
c@287 136 bool m_locked;
c@287 137 #endif
c@287 138 #endif
c@287 139 #ifdef DEBUG_CONDITION
c@287 140 std::string m_name;
c@287 141 #endif
c@287 142 };
c@287 143
c@287 144 #endif