]> Dogcows Code - chaz/yoink/blob - src/Moof/Thread.hh
cade lab fixes
[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
109 Mutex()
110 {
111 mMutex = SDL_CreateMutex();
112 }
113 ~Mutex()
114 {
115 SDL_DestroyMutex(mMutex);
116 }
117
118 bool acquireLock()
119 {
120 return (SDL_LockMutex(mMutex) == 0);
121 }
122 bool releaseLock()
123 {
124 return (SDL_UnlockMutex(mMutex) == 0);
125 }
126
127 class Lock
128 {
129 friend class Condition;
130
131 public:
132
133 Lock(Mutex& mutex)
134 {
135 mMutex = &mutex;
136 mIsLocked = false;
137 }
138 ~Lock()
139 {
140 if (mIsLocked) release();
141 }
142
143 bool acquire()
144 {
145 return (mIsLocked = mMutex->acquireLock());
146 }
147 bool release()
148 {
149 return mMutex->releaseLock();
150 mIsLocked = false;
151 }
152
153 bool isLocked() const
154 {
155 return mIsLocked;
156 }
157
158 protected:
159
160 Mutex* mMutex;
161 bool mIsLocked;
162 };
163
164 class ScopedLock : public Lock
165 {
166 public:
167
168 ScopedLock(Mutex& mutex) :
169 Lock(mutex)
170 {
171 acquire();
172 }
173 };
174
175 private:
176
177 SDL_mutex* mMutex;
178 };
179
180
181 class Condition
182 {
183 public:
184
185 Condition()
186 {
187 condition_ = SDL_CreateCond();
188 }
189 ~Condition()
190 {
191 SDL_DestroyCond(condition_);
192 }
193
194 bool wait(Mutex::Lock& lock)
195 {
196 return (SDL_CondWait(condition_, lock.mMutex->mMutex) == 0);
197 }
198 bool wait(Mutex::Lock& lock, unsigned ms)
199 {
200 // TODO for consistency, this function should take seconds
201 return (SDL_CondWaitTimeout(condition_, lock.mMutex->mMutex, ms) == 0);
202 }
203
204 bool notify()
205 {
206 return (SDL_CondSignal(condition_) == 0);
207 }
208 bool notifyAll()
209 {
210 return (SDL_CondBroadcast(condition_) == 0);
211 }
212
213 private:
214
215 SDL_cond* condition_;
216 };
217
218
219 class Semaphore
220 {
221 public:
222
223 Semaphore(unsigned int value)
224 {
225 semaphore_ = SDL_CreateSemaphore(value);
226 }
227 ~Semaphore()
228 {
229 SDL_DestroySemaphore(semaphore_);
230 }
231
232 bool acquireLock()
233 {
234 return (SDL_SemWait(semaphore_) == 0);
235 }
236 bool releaseLock()
237 {
238 return (SDL_SemPost(semaphore_) == 0);
239 }
240
241 bool tryLock()
242 {
243 return (SDL_SemTryWait(semaphore_) == 0);
244 }
245 bool tryLock(unsigned ms)
246 {
247 // TODO for consistency, this function should take seconds
248 return (SDL_SemWaitTimeout(semaphore_, ms) == 0);
249 }
250
251 class Lock
252 {
253 public:
254
255 Lock(Semaphore& semaphore)
256 {
257 semaphore_ = &semaphore;
258 mIsLocked = false;
259 }
260 ~Lock()
261 {
262 if (mIsLocked) release();
263 }
264
265 bool acquire()
266 {
267 return (mIsLocked = semaphore_->acquireLock());
268 }
269 bool release()
270 {
271 return semaphore_->releaseLock(); mIsLocked = false;
272 }
273
274 bool isLocked() const
275 {
276 return mIsLocked;
277 }
278
279 protected:
280
281 Semaphore* semaphore_;
282 bool mIsLocked;
283 };
284
285 class ScopedLock : public Lock
286 {
287 public:
288
289 ScopedLock(Semaphore& semaphore) :
290 Lock(semaphore)
291 {
292 acquire();
293 }
294 };
295
296 private:
297
298 SDL_sem* semaphore_;
299 };
300
301
302 } // namespace Mf
303
304
305 #endif // _MOOF_THREAD_HH_
306
307 /** vim: set ts=4 sw=4 tw=80: *************************************************/
308
This page took 0.045009 seconds and 4 git commands to generate.