add queen mary 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 #ifdef USE_PTHREADS
17 #include <pthread.h>
18 #endif /* USE_PTHREADS */
19 #endif /* !_WIN32 */
20
21 #include <string>
22
23 //#define DEBUG_THREAD 1
24 //#define DEBUG_MUTEX 1
25 //#define DEBUG_CONDITION 1
26
27 class Thread
28 {
29 public:
30 #ifdef _WIN32
31     typedef HANDLE Id;
32 #else
33 #ifdef USE_PTHREADS
34     typedef pthread_t Id;
35 #endif
36 #endif
37
38     Thread();
39     virtual ~Thread();
40
41     Id id();
42
43     void start();
44     void wait();
45
46     static bool threadingAvailable();
47
48 protected:
49     virtual void run() = 0;
50
51 private:
52 #ifdef _WIN32
53     HANDLE m_id;
54     bool m_extant;
55     static DWORD WINAPI staticRun(LPVOID lpParam);
56 #else
57 #ifdef USE_PTHREADS
58     pthread_t m_id;
59     bool m_extant;
60     static void *staticRun(void *);
61 #endif
62 #endif
63 };
64
65 class Mutex
66 {
67 public:
68     Mutex();
69     ~Mutex();
70
71     void lock();
72     void unlock();
73     bool trylock();
74
75 private:
76 #ifdef _WIN32
77     HANDLE m_mutex;
78 #ifndef NO_THREAD_CHECKS
79     DWORD m_lockedBy;
80 #endif
81 #else
82 #ifdef USE_PTHREADS
83     pthread_mutex_t m_mutex;
84 #ifndef NO_THREAD_CHECKS
85     pthread_t m_lockedBy;
86     bool m_locked;
87 #endif
88 #endif
89 #endif
90 };
91
92 class MutexLocker
93 {
94 public:
95     MutexLocker(Mutex *);
96     ~MutexLocker();
97
98 private:
99     Mutex *m_mutex;
100 };
101
102 class Condition
103 {
104 public:
105     Condition(std::string name);
106     ~Condition();
107
108     // Condition bundles a pthread-style condition variable and mutex
109     // into one class.
110
111     // To wait on a condition, call lock(), test termination variables
112     // as appropriate, and then wait().  The condition will be
113     // unlocked for the duration of the wait() call, which will end
114     // when the condition is signalled.  The condition will be locked
115     // again when wait() returns.
116     //
117     // To signal a condition, call signal().  If the waiting thread
118     // will be performing tests between its own lock() and wait(),
119     // then the signalling thread should also lock() before it signals
120     // (and then unlock afterwards).  If the signalling thread always
121     // locks the mutex during signalling, then the waiting thread
122     // knows that signals will only happen during wait() and not be
123     // missed at other times.
124
125     void lock();
126     void unlock();
127     void wait(int us = 0);
128
129     void signal();
130     
131 private:
132
133 #ifdef _WIN32
134     HANDLE m_mutex;
135     HANDLE m_condition;
136     bool m_locked;
137 #else
138 #ifdef USE_PTHREADS
139     pthread_mutex_t m_mutex;
140     pthread_cond_t m_condition;
141     bool m_locked;
142 #endif
143 #endif
144 #ifdef DEBUG_CONDITION
145     std::string m_name;
146 #endif
147 };
148
149 #endif