14f92dc8cce77dcda09c626fa17771c37e5d3771
[strongswan.git] / src / libstrongswan / threading / thread.c
1 /*
2 * Copyright (C) 2009 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #define _GNU_SOURCE
17 #include <pthread.h>
18 #include <signal.h>
19 #include <semaphore.h>
20
21 #include <library.h>
22 #include <debug.h>
23
24 #include <threading/thread_value.h>
25 #include <threading/mutex.h>
26 #include <utils/linked_list.h>
27
28 #include "thread.h"
29
30 typedef struct private_thread_t private_thread_t;
31
32 struct private_thread_t {
33 /**
34 * Public interface.
35 */
36 thread_t public;
37
38 /**
39 * Human-readable ID of this thread.
40 */
41 u_int id;
42
43 /**
44 * ID of the underlying thread.
45 */
46 pthread_t thread_id;
47
48 /**
49 * Main function of this thread (NULL for the main thread).
50 */
51 thread_main_t main;
52
53 /**
54 * Argument for the main function.
55 */
56 void *arg;
57
58 /**
59 * Stack of cleanup handlers.
60 */
61 linked_list_t *cleanup_handlers;
62
63 /**
64 * Mutex to make modifying thread properties safe.
65 */
66 mutex_t *mutex;
67
68 /**
69 * Semaphore used to sync the creation/start of the thread.
70 */
71 sem_t created;
72
73 /**
74 * TRUE if this thread has been detached or joined, i.e. can be cleaned
75 * up after terminating.
76 */
77 bool detached_or_joined;
78
79 /**
80 * TRUE if the threads has terminated (cancelled, via thread_exit or
81 * returned from the main function)
82 */
83 bool terminated;
84
85 };
86
87 typedef struct {
88 /**
89 * Cleanup callback function.
90 */
91 thread_cleanup_t cleanup;
92
93 /**
94 * Argument provided to the cleanup function.
95 */
96 void *arg;
97
98 } cleanup_handler_t;
99
100
101 /**
102 * Next thread ID.
103 */
104 static u_int next_id = 1;
105
106 /**
107 * Mutex to safely access the next thread ID.
108 */
109 static mutex_t *id_mutex;
110
111 /**
112 * Store the thread object in a thread-specific value.
113 */
114 static thread_value_t *current_thread;
115
116
117 /**
118 * Destroy an internal thread object.
119 *
120 * @note The mutex of this thread object has to be locked, it gets unlocked
121 * automatically.
122 */
123 static void thread_destroy(private_thread_t *this)
124 {
125 if (!this->terminated || !this->detached_or_joined)
126 {
127 this->mutex->unlock(this->mutex);
128 return;
129 }
130 this->cleanup_handlers->destroy(this->cleanup_handlers);
131 this->mutex->unlock(this->mutex);
132 this->mutex->destroy(this->mutex);
133 sem_destroy(&this->created);
134 free(this);
135 }
136
137 /**
138 * Implementation of thread_t.cancel.
139 */
140 static void cancel(private_thread_t *this)
141 {
142 this->mutex->lock(this->mutex);
143 if (pthread_equal(this->thread_id, pthread_self()))
144 {
145 this->mutex->unlock(this->mutex);
146 DBG1("!!! CANNOT CANCEL CURRENT THREAD !!!");
147 return;
148 }
149 pthread_cancel(this->thread_id);
150 this->mutex->unlock(this->mutex);
151 }
152
153 /**
154 * Implementation of thread_t.kill.
155 */
156 static void _kill(private_thread_t *this, int sig)
157 {
158 this->mutex->lock(this->mutex);
159 if (pthread_equal(this->thread_id, pthread_self()))
160 {
161 /* it might actually be possible to send a signal to pthread_self (there
162 * is an example in raise(3) describing that), the problem is though,
163 * that the thread only returns here after the signal handler has
164 * returned, so depending on the signal, the lock might not get
165 * unlocked. */
166 this->mutex->unlock(this->mutex);
167 DBG1("!!! CANNOT SEND SIGNAL TO CURRENT THREAD !!!");
168 return;
169 }
170 pthread_kill(this->thread_id, sig);
171 this->mutex->unlock(this->mutex);
172 }
173
174 /**
175 * Implementation of thread_t.cancel.
176 */
177 static void detach(private_thread_t *this)
178 {
179 this->mutex->lock(this->mutex);
180 pthread_detach(this->thread_id);
181 this->detached_or_joined = TRUE;
182 thread_destroy(this);
183 }
184
185 /**
186 * Implementation of thread_t.cancel.
187 */
188 static void *join(private_thread_t *this)
189 {
190 pthread_t thread_id;
191 void *val;
192 this->mutex->lock(this->mutex);
193 if (pthread_equal(this->thread_id, pthread_self()))
194 {
195 this->mutex->unlock(this->mutex);
196 DBG1("!!! CANNOT JOIN CURRENT THREAD !!!");
197 return NULL;
198 }
199 if (this->detached_or_joined)
200 {
201 this->mutex->unlock(this->mutex);
202 DBG1("!!! CANNOT JOIN DETACHED THREAD !!!");
203 return NULL;
204 }
205 thread_id = this->thread_id;
206 this->detached_or_joined = TRUE;
207 if (this->terminated)
208 {
209 /* thread has terminated before the call to join */
210 thread_destroy(this);
211 }
212 else
213 {
214 /* thread_destroy is called when the thread terminates normally */
215 this->mutex->unlock(this->mutex);
216 }
217 pthread_join(thread_id, &val);
218 return val;
219 }
220
221 /**
222 * Create an internal thread object.
223 */
224 static private_thread_t *thread_create_internal()
225 {
226 private_thread_t *this = malloc_thing(private_thread_t);
227 this->public.cancel = (void(*)(thread_t*))cancel;
228 this->public.kill = (void(*)(thread_t*,int))_kill;
229 this->public.detach = (void(*)(thread_t*))detach;
230 this->public.join = (void*(*)(thread_t*))join;
231
232 this->id = 0;
233 this->thread_id = 0;
234 this->main = NULL;
235 this->arg = NULL;
236 this->cleanup_handlers = linked_list_create();
237 this->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
238 sem_init(&this->created, FALSE, 0);
239 this->detached_or_joined = FALSE;
240 this->terminated = FALSE;
241
242 return this;
243 }
244
245 /**
246 * Main cleanup function for threads.
247 */
248 static void thread_cleanup(private_thread_t *this)
249 {
250 cleanup_handler_t *handler;
251 this->mutex->lock(this->mutex);
252 while (this->cleanup_handlers->remove_last(this->cleanup_handlers,
253 (void**)&handler) == SUCCESS)
254 {
255 handler->cleanup(handler->arg);
256 free(handler);
257 }
258 this->terminated = TRUE;
259 thread_destroy(this);
260 }
261
262 /**
263 * Main function wrapper for threads.
264 */
265 static void *thread_main(private_thread_t *this)
266 {
267 void *res;
268 sem_wait(&this->created);
269 current_thread->set(current_thread, this);
270 pthread_cleanup_push((thread_cleanup_t)thread_cleanup, this);
271 res = this->main(this->arg);
272 pthread_cleanup_pop(TRUE);
273 return res;
274 }
275
276 /**
277 * Described in header.
278 */
279 thread_t *thread_create(thread_main_t main, void *arg)
280 {
281 private_thread_t *this = thread_create_internal();
282 this->main = main;
283 this->arg = arg;
284 if (pthread_create(&this->thread_id, NULL, (void*)thread_main, this) != 0)
285 {
286 DBG1("failed to create thread!");
287 thread_destroy(this);
288 return NULL;
289 }
290 id_mutex->lock(id_mutex);
291 this->id = next_id++;
292 id_mutex->unlock(id_mutex);
293 sem_post(&this->created);
294 return &this->public;
295 }
296
297 /**
298 * Described in header.
299 */
300 thread_t *thread_current()
301 {
302 return current_thread->get(current_thread);
303 }
304
305 /**
306 * Described in header.
307 */
308 u_int thread_current_id()
309 {
310 private_thread_t *this = (private_thread_t*)thread_current();
311 return this->id;
312 }
313
314 /**
315 * Described in header.
316 */
317 void thread_cleanup_push(thread_cleanup_t cleanup, void *arg)
318 {
319 private_thread_t *this = (private_thread_t*)thread_current();
320 cleanup_handler_t *handler;
321 this->mutex->lock(this->mutex);
322 handler = malloc_thing(cleanup_handler_t);
323 handler->cleanup = cleanup;
324 handler->arg = arg;
325 this->cleanup_handlers->insert_last(this->cleanup_handlers, handler);
326 this->mutex->unlock(this->mutex);
327 }
328
329 /**
330 * Described in header.
331 */
332 void thread_cleanup_pop(bool execute)
333 {
334 private_thread_t *this = (private_thread_t*)thread_current();
335 cleanup_handler_t *handler;
336 this->mutex->lock(this->mutex);
337 if (this->cleanup_handlers->remove_last(this->cleanup_handlers,
338 (void**)&handler) != SUCCESS)
339 {
340 this->mutex->unlock(this->mutex);
341 DBG1("!!! THREAD CLEANUP ERROR !!!");
342 return;
343 }
344 this->mutex->unlock(this->mutex);
345
346 if (execute)
347 {
348 handler->cleanup(handler->arg);
349 }
350 free(handler);
351 }
352
353 /**
354 * Described in header.
355 */
356 bool thread_cancelability(bool enable)
357 {
358 int old;
359 pthread_setcancelstate(enable ? PTHREAD_CANCEL_ENABLE
360 : PTHREAD_CANCEL_DISABLE, &old);
361 return old == PTHREAD_CANCEL_ENABLE;
362 }
363
364 /**
365 * Described in header.
366 */
367 void thread_cancellation_point()
368 {
369 bool old = thread_cancelability(TRUE);
370 pthread_testcancel();
371 thread_cancelability(old);
372 }
373
374 /**
375 * Described in header.
376 */
377 void thread_exit(void *val)
378 {
379 pthread_exit(val);
380 }
381
382 /**
383 * Described in header.
384 */
385 void threads_init()
386 {
387 private_thread_t *main_thread = thread_create_internal();
388 main_thread->id = 0;
389 main_thread->thread_id = pthread_self();
390 current_thread = thread_value_create(NULL);
391 current_thread->set(current_thread, (void*)main_thread);
392 id_mutex = mutex_create(MUTEX_TYPE_DEFAULT);
393 }
394
395 /**
396 * Described in header.
397 */
398 void threads_deinit()
399 {
400 private_thread_t *main_thread = (private_thread_t*)thread_current();
401 thread_destroy(main_thread);
402 current_thread->destroy(current_thread);
403 id_mutex->destroy(id_mutex);
404 }
405