Merge branch 'master' into windows
[ardour.git] / libs / rubberband / src / Thread.h
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
2
3 /*
4     Rubber Band
5     An audio time-stretching and pitch-shifting library.
6     Copyright 2007-2008 Chris Cannam.
7     
8     This program is free software; you can redistribute it and/or
9     modify it under the terms of the GNU General Public License as
10     published by the Free Software Foundation; either version 2 of the
11     License, or (at your option) any later version.  See the file
12     COPYING included with this distribution for more information.
13 */
14
15 #ifndef _RUBBERBAND_THREAD_H_
16 #define _RUBBERBAND_THREAD_H_
17
18 #ifdef PLATFORM_WINDOWS
19 #include <windows.h>
20 #else /* !PLATFORM_WINDOWS */
21 #include <pthread.h>
22 #endif /* !PLATFORM_WINDOWS */
23
24 #include <string>
25
26 //#define DEBUG_THREAD 1
27 //#define DEBUG_MUTEX 1
28 //#define DEBUG_CONDITION 1
29
30 namespace RubberBand
31 {
32
33 class Thread
34 {
35 public:
36 #ifdef PLATFORM_WINDOWS
37     typedef HANDLE Id;
38 #else
39     typedef pthread_t Id;
40 #endif
41
42     Thread();
43     virtual ~Thread();
44
45     Id id();
46
47     void start();
48     void wait();
49
50     static bool threadingAvailable();
51
52 protected:
53     virtual void run() = 0;
54
55 private:
56 #ifdef PLATFORM_WINDOWS
57     HANDLE m_id;
58     bool m_extant;
59     static DWORD WINAPI staticRun(LPVOID lpParam);
60 #else
61     pthread_t m_id;
62     bool m_extant;
63     static void *staticRun(void *);
64 #endif
65 };
66
67 class Mutex
68 {
69 public:
70     Mutex();
71     ~Mutex();
72
73     void lock();
74     void unlock();
75     bool trylock();
76
77 private:
78 #ifdef PLATFORM_WINDOWS
79     HANDLE m_mutex;
80 #ifndef NO_THREAD_CHECKS
81     DWORD m_lockedBy;
82 #endif
83 #else
84     pthread_mutex_t m_mutex;
85 #ifndef NO_THREAD_CHECKS
86     pthread_t m_lockedBy;
87     bool m_locked;
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     // To wait on a condition, either simply call wait(), or call
109     // lock() and then wait() (perhaps testing some state in between).
110     // To signal a condition, call signal().
111
112     // Although any thread may signal on a given condition, only one
113     // thread should ever wait on any given condition object --
114     // otherwise there will be a race conditions in the logic that
115     // avoids the thread code having to track whether the condition's
116     // mutex is locked or not.  If that is your requirement, this
117     // Condition wrapper is not for you.
118     void lock();
119     void unlock();
120     void wait(int us = 0);
121
122     void signal();
123     
124 private:
125
126 #ifdef PLATFORM_WINDOWS
127     HANDLE m_mutex;
128     HANDLE m_condition;
129     bool m_locked;
130 #else
131     pthread_mutex_t m_mutex;
132     pthread_cond_t m_condition;
133     bool m_locked;
134 #endif
135 #ifdef DEBUG_CONDITION
136     std::string m_name;
137 #endif
138 };
139
140 }
141
142 #endif