]> Dogcows Code - chaz/yoink/blob - src/Moof/Thread.hh
52a878a553d68ebf26d33320dfebb2494a9af457
[chaz/yoink] / src / Moof / Thread.hh
1
2 /*] Copyright (c) 2009-2010, Charles McGarvey [**************************
3 **] All rights reserved.
4 *
5 * vi:ts=4 sw=4 tw=75
6 *
7 * Distributable under the terms and conditions of the 2-clause BSD license;
8 * see the file COPYING for a complete text of the license.
9 *
10 **************************************************************************/
11
12 #ifndef _MOOF_THREAD_HH_
13 #define _MOOF_THREAD_HH_
14
15 /**
16 * @file Thread.hh
17 * Light C++ wrapper around the SDL threads API.
18 */
19
20 #include <boost/function.hpp>
21 #include <SDL/SDL.h>
22
23
24 namespace Mf {
25
26 //
27 // The detach function detaches a separate thread by calling 'func' with
28 // the 'arg' parameter.
29 //
30
31 typedef SDL_Thread* Thread;
32
33 typedef boost::function<int(void)> Function;
34
35
36 inline int detach_(void* arg)
37 {
38 //Function function = *(Function*)arg;
39 int code = (*(Function*)arg)();
40
41 delete (Function*)arg;
42 return code;
43 }
44
45 inline Thread detachFunction(const Function& function)
46 {
47 Function* fcopy = new Function(function);
48 Thread thread = SDL_CreateThread(detach_, (void*)fcopy);
49
50 if (thread == 0) delete fcopy;
51 return thread;
52 }
53
54
55 inline int waitOnThread(Thread thread)
56 {
57 int i;
58 SDL_WaitThread(thread, &i);
59 return i;
60 }
61
62 inline void killThread(Thread thread)
63 {
64 SDL_KillThread(thread);
65 }
66
67
68 //
69 // The identifier function returns a unique integer for the calling thread.
70 //
71
72 inline unsigned getThreadIdentifier()
73 {
74 return SDL_ThreadID();
75 }
76
77 inline unsigned getThreadIdentifier(Thread thread)
78 {
79 return SDL_GetThreadID(thread);
80 }
81
82
83 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
84
85 class Mutex
86 {
87 friend class Condition;
88
89 public:
90
91 Mutex()
92 {
93 mMutex = SDL_CreateMutex();
94 }
95 ~Mutex()
96 {
97 SDL_DestroyMutex(mMutex);
98 }
99
100 bool acquireLock()
101 {
102 return (SDL_LockMutex(mMutex) == 0);
103 }
104 bool releaseLock()
105 {
106 return (SDL_UnlockMutex(mMutex) == 0);
107 }
108
109 class Lock
110 {
111 friend class Condition;
112
113 public:
114
115 Lock(Mutex& mutex)
116 {
117 mMutex = &mutex;
118 mIsLocked = false;
119 }
120 ~Lock()
121 {
122 if (mIsLocked) release();
123 }
124
125 bool acquire()
126 {
127 return (mIsLocked = mMutex->acquireLock());
128 }
129 bool release()
130 {
131 return mMutex->releaseLock();
132 mIsLocked = false;
133 }
134
135 bool isLocked() const
136 {
137 return mIsLocked;
138 }
139
140 protected:
141
142 Mutex* mMutex;
143 bool mIsLocked;
144 };
145
146 class ScopedLock : public Lock
147 {
148 public:
149
150 ScopedLock(Mutex& mutex) :
151 Lock(mutex)
152 {
153 acquire();
154 }
155 };
156
157 private:
158
159 SDL_mutex* mMutex;
160 };
161
162
163 class Condition
164 {
165 public:
166
167 Condition()
168 {
169 condition_ = SDL_CreateCond();
170 }
171 ~Condition()
172 {
173 SDL_DestroyCond(condition_);
174 }
175
176 bool wait(Mutex::Lock& lock)
177 {
178 return (SDL_CondWait(condition_, lock.mMutex->mMutex) == 0);
179 }
180 bool wait(Mutex::Lock& lock, unsigned ms)
181 {
182 // TODO for consistency, this function should take seconds
183 return (SDL_CondWaitTimeout(condition_,
184 lock.mMutex->mMutex, ms) == 0);
185 }
186
187 bool notify()
188 {
189 return (SDL_CondSignal(condition_) == 0);
190 }
191 bool notifyAll()
192 {
193 return (SDL_CondBroadcast(condition_) == 0);
194 }
195
196 private:
197
198 SDL_cond* condition_;
199 };
200
201
202 class Semaphore
203 {
204 public:
205
206 Semaphore(unsigned int value)
207 {
208 semaphore_ = SDL_CreateSemaphore(value);
209 }
210 ~Semaphore()
211 {
212 SDL_DestroySemaphore(semaphore_);
213 }
214
215 bool acquireLock()
216 {
217 return (SDL_SemWait(semaphore_) == 0);
218 }
219 bool releaseLock()
220 {
221 return (SDL_SemPost(semaphore_) == 0);
222 }
223
224 bool tryLock()
225 {
226 return (SDL_SemTryWait(semaphore_) == 0);
227 }
228 bool tryLock(unsigned ms)
229 {
230 // TODO for consistency, this function should take seconds
231 return (SDL_SemWaitTimeout(semaphore_, ms) == 0);
232 }
233
234 class Lock
235 {
236 public:
237
238 Lock(Semaphore& semaphore)
239 {
240 semaphore_ = &semaphore;
241 mIsLocked = false;
242 }
243 ~Lock()
244 {
245 if (mIsLocked) release();
246 }
247
248 bool acquire()
249 {
250 return (mIsLocked = semaphore_->acquireLock());
251 }
252 bool release()
253 {
254 return semaphore_->releaseLock(); mIsLocked = false;
255 }
256
257 bool isLocked() const
258 {
259 return mIsLocked;
260 }
261
262 protected:
263
264 Semaphore* semaphore_;
265 bool mIsLocked;
266 };
267
268 class ScopedLock : public Lock
269 {
270 public:
271
272 ScopedLock(Semaphore& semaphore) :
273 Lock(semaphore)
274 {
275 acquire();
276 }
277 };
278
279 private:
280
281 SDL_sem* semaphore_;
282 };
283
284
285 } // namespace Mf
286
287 #endif // _MOOF_THREAD_HH_
288
This page took 0.047581 seconds and 3 git commands to generate.