5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2006 - 2007 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
23 /**************************** SILC Thread API *******************************/
25 /* Thread structure for Symbian */
28 SilcThreadStart start_func;
36 /* The actual thread function */
38 static TInt silc_thread_start(TAny *context)
41 SilcSymbianThread tc = (SilcSymbianThread)context;
42 SilcThreadStart start_func = tc->start_func;
43 void *context = tc->context;
44 SilcBool waitable = tc->waitable;
48 /* Call the thread function */
50 silc_thread_exit(start_func(context));
58 /* Executed new thread */
60 SilcThread silc_thread_create(SilcThreadStart start_func, void *context,
69 SILC_LOG_DEBUG(("Creating new thread"));
71 tc = (SilcSymbianThread)silc_calloc(1, sizeof(*thread));
74 tc->start_func = start_func;
75 tc->context = context;
76 tc->waitable = waitable;
79 thread = new RThread();
85 /* Create the thread */
86 name = (TText *)silc_time_string(0);
87 ret = thread->Create(name, silc_thread_start, 8192, 4096, 1024 * 1024,
89 if (ret != KErrNone) {
90 SILC_LOG_ERROR(("Could not create new thread"));
96 /* Start the thread */
99 /* Close our instance to the thread */
102 return (SilcThread)thread;
104 /* Call thread callback immediately */
105 (*start_func)(context);
110 /* Exits current thread */
112 void silc_thread_exit(void *exit_value)
115 RThread().Kill((Tint)exit_value);
119 /* Returns current thread context */
121 SilcThread silc_thread_self(void)
124 return (SilcThread)&RThread();
130 /* Blocks calling thread to wait for `thread' to finish. */
132 SilcBool silc_thread_wait(SilcThread thread, void **exit_value)
136 RThread *t = (RThread *)thread;
138 User::WaitForAnyRequest();
145 /***************************** SILC Mutex API *******************************/
147 /* SILC Mutex structure */
148 struct SilcMutexStruct {
151 #endif /* SILC_THREADS */
152 unsigned int locked : 1;
155 SilcBool silc_mutex_alloc(SilcMutex *mutex)
158 *mutex = (SilcMutex)silc_calloc(1, sizeof(**mutex));
161 (*mutex)->mutex = new RMutex();
162 if (!(*mutex)->mutex) {
166 if ((*mutex)->mutex->CreateLocal() != KErrNone) {
167 delete (*mutex)->mutex;
171 (*mutex)->locked = FALSE;
175 #endif /* SILC_THREADS */
178 void silc_mutex_free(SilcMutex mutex)
182 mutex->mutex->Close();
186 #endif /* SILC_THREADS */
189 void silc_mutex_lock(SilcMutex mutex)
193 mutex->mutex->Wait();
194 mutex->locked = TRUE;
196 #endif /* SILC_THREADS */
199 void silc_mutex_unlock(SilcMutex mutex)
203 mutex->mutex->Signal();
204 mutex->locked = FALSE;
206 #endif /* SILC_THREADS */
209 void silc_mutex_assert_locked(SilcMutex mutex)
213 SILC_ASSERT(mutex->locked);
214 #endif /* SILC_THREADS */
217 /***************************** SILC Rwlock API *****************************/
219 /* SILC read/write lock structure */
220 struct SilcRwLockStruct {
224 #endif /* SILC_THREADS */
225 unsigned int readers : 31;
226 unsigned int locked : 1;
229 SilcBool silc_rwlock_alloc(SilcRwLock *rwlock)
232 *rwlock = (SilcRwLock)silc_calloc(1, sizeof(**rwlock));
235 if (!silc_mutex_alloc(&(*rwlock)->mutex)) {
239 if (!silc_cond_alloc(&(*rwlock)->cond)) {
240 silc_mutex_free((*rwlock)->mutex);
247 #endif /* SILC_THREADS */
250 void silc_rwlock_free(SilcRwLock rwlock)
254 silc_mutex_free(rwlock->mutex);
255 silc_cond_free(rwlock->cond);
258 #endif /* SILC_THREADS */
261 void silc_rwlock_rdlock(SilcRwLock rwlock)
265 silc_mutex_lock(rwlock->mutex);
267 silc_mutex_unlock(rwlock->mutex);
269 #endif /* SILC_THREADS */
272 void silc_rwlock_wrlock(SilcRwLock rwlock)
276 silc_mutex_lock(rwlock->mutex);
277 while (rwlock->readers > 0)
278 silc_cond_wait(rwlock->cond, rwlock->mutex);
279 rwlock->locked = TRUE;
281 #endif /* SILC_THREADS */
284 void silc_rwlock_unlock(SilcRwLock rwlock)
288 if (rwlock->locked) {
290 rwlock->locked = FALSE;
291 silc_mutex_unlock(rwlock->mutex);
296 silc_mutex_lock(rwlock->mutex);
298 silc_cond_broadcast(rwlock->cond);
299 silc_mutex_unlock(rwlock->mutex);
301 #endif /* SILC_THREADS */
304 /****************************** SILC Cond API *******************************/
306 /* SILC Conditional Variable context */
307 struct SilcCondStruct {
312 #endif /* SILC_THREADS*/
315 SilcBool silc_cond_alloc(SilcCond *cond)
318 *cond = (SilcCond)silc_calloc(1, sizeof(**cond));
321 (*cond)->cond = new RCondVar();
322 if (!(*cond)->cond) {
326 if ((*cond)->cond->CreateLocal() != KErrNone) {
327 delete (*cond)->cond;
334 #endif /* SILC_THREADS*/
337 void silc_cond_free(SilcCond cond)
343 #endif /* SILC_THREADS*/
346 void silc_cond_signal(SilcCond cond)
349 cond->cond->Signal();
350 #endif /* SILC_THREADS*/
353 void silc_cond_broadcast(SilcCond cond)
356 cond->cond->Broadcast();
357 #endif /* SILC_THREADS*/
360 void silc_cond_wait(SilcCond cond, SilcMutex mutex)
363 cond->cond->Wait(*mutex->mutex);
364 #endif /* SILC_THREADS*/
367 SilcBool silc_cond_timedwait(SilcCond cond, SilcMutex mutex,
372 return (cond->cond->TimedWait(*mutex->mutex, (TInt)timeout * 1000) ==
374 return (cond->cond->Wait(*mutex->mutex) == KErrNone);
377 #endif /* SILC_THREADS*/