update qm-dsp library
[ardour.git] / libs / qm-dsp / thread / Thread.h
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
2
3 /*
4     QM DSP Library
5
6     Centre for Digital Music, Queen Mary, University of London.
7     This file copyright Chris Cannam, used with permission.
8 */
9
10 #ifndef _THREAD_H_
11 #define _THREAD_H_
12
13 #ifdef _WIN32
14 #include <windows.h>
15 #else /* !_WIN32 */
16 #define USE_PTHREADS
17 #ifdef USE_PTHREADS
18 #include <pthread.h>
19 #else
20 #error Must have either _WIN32 or USE_PTHREADS defined
21 #endif /* USE_PTHREADS */
22 #endif /* !_WIN32 */
23
24 #include <string>
25
26 //#define DEBUG_THREAD 1
27 //#define DEBUG_MUTEX 1
28 //#define DEBUG_CONDITION 1
29
30 class Thread
31 {
32 public:
33 #ifdef _WIN32
34     typedef HANDLE Id;
35 #else
36 #ifdef USE_PTHREADS
37     typedef pthread_t Id;
38 #endif
39 #endif
40
41     Thread();
42     virtual ~Thread();
43
44     Id id();
45
46     void start();
47     void wait();
48
49     static bool threadingAvailable();
50
51 protected:
52     virtual void run() = 0;
53
54 private:
55 #ifdef _WIN32
56     HANDLE m_id;
57     bool m_extant;
58     static DWORD WINAPI staticRun(LPVOID lpParam);
59 #else
60 #ifdef USE_PTHREADS
61     pthread_t m_id;
62     bool m_extant;
63     static void *staticRun(void *);
64 #endif
65 #endif
66 };
67
68 class Mutex
69 {
70 public:
71     Mutex();
72     ~Mutex();
73
74     void lock();
75     void unlock();
76     bool trylock();
77
78 private:
79 #ifdef _WIN32
80     HANDLE m_mutex;
81 #ifndef NO_THREAD_CHECKS
82     DWORD m_lockedBy;
83 #endif
84 #else
85 #ifdef USE_PTHREADS
86     pthread_mutex_t m_mutex;
87 #ifndef NO_THREAD_CHECKS
88     pthread_t m_lockedBy;
89     bool m_locked;
90 #endif
91 #endif
92 #endif
93 };
94
95 class MutexLocker
96 {
97 public:
98     MutexLocker(Mutex *);
99     ~MutexLocker();
100
101 private:
102     Mutex *m_mutex;
103 };
104
105 class Condition
106 {
107 public:
108     Condition(std::string name);
109     ~Condition();
110
111     // Condition bundles a pthread-style condition variable and mutex
112     // into one class.
113
114     // To wait on a condition, call lock(), test termination variables
115     // as appropriate, and then wait().  The condition will be
116     // unlocked for the duration of the wait() call, which will end
117     // when the condition is signalled.  The condition will be locked
118     // again when wait() returns.
119     //
120     // To signal a condition, call signal().  If the waiting thread
121     // will be performing tests between its own lock() and wait(),
122     // then the signalling thread should also lock() before it signals
123     // (and then unlock afterwards).  If the signalling thread always
124     // locks the mutex during signalling, then the waiting thread
125     // knows that signals will only happen during wait() and not be
126     // missed at other times.
127
128     void lock();
129     void unlock();
130     void wait(int us = 0);
131
132     void signal();
133     
134 private:
135
136 #ifdef _WIN32
137     HANDLE m_mutex;
138     HANDLE m_condition;
139     bool m_locked;
140 #else
141 #ifdef USE_PTHREADS
142     pthread_mutex_t m_mutex;
143     pthread_cond_t m_condition;
144     bool m_locked;
145 #endif
146 #endif
147 #ifdef DEBUG_CONDITION
148     std::string m_name;
149 #endif
150 };
151
152 #endif