]> Dogcows Code - chaz/yoink/blob - src/Moof/Thread.hh
new timer class
[chaz/yoink] / src / Moof / Thread.hh
1
2 /*******************************************************************************
3
4 Copyright (c) 2009, Charles McGarvey
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9
10 * Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright notice,
13 this list of conditions and the following disclaimer in the documentation
14 and/or other materials provided with the distribution.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27 *******************************************************************************/
28
29 #ifndef _MOOF_THREAD_HH_
30 #define _MOOF_THREAD_HH_
31
32 /**
33 * @file Thread.hh
34 * Light C++ wrapper around the SDL threads API.
35 */
36
37 #include <boost/function.hpp>
38
39 #include <SDL/SDL.h>
40
41
42 namespace Mf {
43
44 //
45 // The detach function detaches a separate thread by calling 'func' with
46 // the 'arg' parameter.
47 //
48
49 typedef SDL_Thread* Thread;
50
51 typedef boost::function<int(void)> Function;
52
53
54 inline int detach_(void* arg)
55 {
56 //Function function = *(Function*)arg;
57 int code = (*(Function*)arg)();
58
59 delete (Function*)arg;
60 return code;
61 }
62
63 inline Thread detachFunction(const Function& function)
64 {
65 Function* fcopy = new Function(function);
66 Thread thread = SDL_CreateThread(detach_, (void*)fcopy);
67
68 if (thread == 0) delete fcopy;
69 return thread;
70 }
71
72
73 inline int waitOnThread(Thread thread)
74 {
75 int i;
76 SDL_WaitThread(thread, &i);
77 return i;
78 }
79
80 inline void killThread(Thread thread)
81 {
82 SDL_KillThread(thread);
83 }
84
85
86 //
87 // The identifier function returns a unique integer for the calling thread.
88 //
89
90 inline unsigned getThreadIdentifier()
91 {
92 return SDL_ThreadID();
93 }
94
95 inline unsigned getThreadIdentifier(Thread thread)
96 {
97 return SDL_GetThreadID(thread);
98 }
99
100
101 // =============================================================================
102
103 class Mutex
104 {
105 friend class Condition;
106
107 public:
108 Mutex()
109 {
110 mutex_ = SDL_CreateMutex();
111 }
112 ~Mutex()
113 {
114 SDL_DestroyMutex(mutex_);
115 }
116
117 bool acquireLock()
118 {
119 return (SDL_LockMutex(mutex_) == 0);
120 }
121 bool releaseLock()
122 {
123 return (SDL_UnlockMutex(mutex_) == 0);
124 }
125
126 class Lock
127 {
128 friend class Condition;
129
130 public:
131 Lock(Mutex& mutex)
132 {
133 mutex_ = &mutex;
134 isLocked_ = false;
135 }
136 ~Lock()
137 {
138 if (isLocked_) release();
139 }
140
141 bool acquire()
142 {
143 return (isLocked_ = mutex_->acquireLock());
144 }
145 bool release()
146 {
147 return mutex_->releaseLock();
148 isLocked_ = false;
149 }
150
151 bool isLocked() const
152 {
153 return isLocked_;
154 }
155
156 protected:
157 Mutex* mutex_;
158 bool isLocked_;
159 };
160
161 class ScopedLock : public Lock
162 {
163 public:
164 ScopedLock(Mutex& mutex) :
165 Lock(mutex)
166 {
167 acquire();
168 }
169 };
170
171 private:
172 SDL_mutex* mutex_;
173 };
174
175
176 class Condition
177 {
178 public:
179 Condition()
180 {
181 condition_ = SDL_CreateCond();
182 }
183 ~Condition()
184 {
185 SDL_DestroyCond(condition_);
186 }
187
188 bool wait(Mutex::Lock& lock)
189 {
190 return (SDL_CondWait(condition_, lock.mutex_->mutex_) == 0);
191 }
192 bool wait(Mutex::Lock& lock, unsigned ms)
193 {
194 // TODO for consistency, this function should take seconds
195 return (SDL_CondWaitTimeout(condition_, lock.mutex_->mutex_, ms) == 0);
196 }
197
198 bool notify()
199 {
200 return (SDL_CondSignal(condition_) == 0);
201 }
202 bool notifyAll()
203 {
204 return (SDL_CondBroadcast(condition_) == 0);
205 }
206
207 private:
208 SDL_cond* condition_;
209 };
210
211
212 class Semaphore
213 {
214 public:
215 Semaphore(unsigned int value)
216 {
217 semaphore_ = SDL_CreateSemaphore(value);
218 }
219 ~Semaphore()
220 {
221 SDL_DestroySemaphore(semaphore_);
222 }
223
224 bool acquireLock()
225 {
226 return (SDL_SemWait(semaphore_) == 0);
227 }
228 bool releaseLock()
229 {
230 return (SDL_SemPost(semaphore_) == 0);
231 }
232
233 bool tryLock()
234 {
235 return (SDL_SemTryWait(semaphore_) == 0);
236 }
237 bool tryLock(unsigned ms)
238 {
239 // TODO for consistency, this function should take seconds
240 return (SDL_SemWaitTimeout(semaphore_, ms) == 0);
241 }
242
243 class Lock
244 {
245 public:
246 Lock(Semaphore& semaphore)
247 {
248 semaphore_ = &semaphore;
249 isLocked_ = false;
250 }
251 ~Lock()
252 {
253 if (isLocked_) release();
254 }
255
256 bool acquire()
257 {
258 return (isLocked_ = semaphore_->acquireLock());
259 }
260 bool release()
261 {
262 return semaphore_->releaseLock(); isLocked_ = false;
263 }
264
265 bool isLocked() const
266 {
267 return isLocked_;
268 }
269
270 protected:
271 Semaphore* semaphore_;
272 bool isLocked_;
273 };
274
275 class ScopedLock : public Lock
276 {
277 public:
278 ScopedLock(Semaphore& semaphore) :
279 Lock(semaphore)
280 {
281 acquire();
282 }
283 };
284
285 private:
286 SDL_sem* semaphore_;
287 };
288
289
290 } // namespace Mf
291
292
293 #endif // _MOOF_THREAD_HH_
294
295 /** vim: set ts=4 sw=4 tw=80: *************************************************/
296
This page took 0.042753 seconds and 5 git commands to generate.