2bf86c1589ff4bd701730e7a29d96ff6db12d14f
[strongswan.git] / src / libstrongswan / threading / thread.c
1 /*
2 * Copyright (C) 2009-2012 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
20 #ifdef HAVE_GETTID
21 #include <sys/types.h>
22 #include <unistd.h>
23 #endif
24
25 #ifdef HAVE_SYS_GETTID
26 #include <sys/syscall.h>
27 static inline pid_t gettid()
28 {
29 return syscall(SYS_gettid);
30 }
31 #endif
32
33 #include <library.h>
34 #include <utils/debug.h>
35
36 #include <threading/thread_value.h>
37 #include <threading/mutex.h>
38 #include <collections/linked_list.h>
39
40 #include "thread.h"
41
42 typedef struct private_thread_t private_thread_t;
43
44 struct private_thread_t {
45 /**
46 * Public interface.
47 */
48 thread_t public;
49
50 /**
51 * Human-readable ID of this thread.
52 */
53 u_int id;
54
55 /**
56 * ID of the underlying thread.
57 */
58 pthread_t thread_id;
59
60 /**
61 * Main function of this thread (NULL for the main thread).
62 */
63 thread_main_t main;
64
65 /**
66 * Argument for the main function.
67 */
68 void *arg;
69
70 /**
71 * Stack of cleanup handlers.
72 */
73 linked_list_t *cleanup_handlers;
74
75 /**
76 * Mutex to make modifying thread properties safe.
77 */
78 mutex_t *mutex;
79
80 /**
81 * TRUE if this thread has been detached or joined, i.e. can be cleaned
82 * up after terminating.
83 */
84 bool detached_or_joined;
85
86 /**
87 * TRUE if the threads has terminated (cancelled, via thread_exit or
88 * returned from the main function)
89 */
90 bool terminated;
91
92 };
93
94 typedef struct {
95 /**
96 * Cleanup callback function.
97 */
98 thread_cleanup_t cleanup;
99
100 /**
101 * Argument provided to the cleanup function.
102 */
103 void *arg;
104
105 } cleanup_handler_t;
106
107
108 /**
109 * Next thread ID.
110 */
111 static u_int next_id;
112
113 /**
114 * Mutex to safely access the next thread ID.
115 */
116 static mutex_t *id_mutex;
117
118 /**
119 * Store the thread object in a thread-specific value.
120 */
121 static thread_value_t *current_thread;
122
123
124 #ifndef HAVE_PTHREAD_CANCEL
125 /* if pthread_cancel is not available, we emulate it using a signal */
126 #ifdef ANDROID
127 #define SIG_CANCEL SIGUSR2
128 #else
129 #define SIG_CANCEL (SIGRTMIN+7)
130 #endif
131
132 /* the signal handler for SIG_CANCEL uses pthread_exit to terminate the
133 * "cancelled" thread */
134 static void cancel_signal_handler(int sig)
135 {
136 pthread_exit(NULL);
137 }
138 #endif
139
140
141 /**
142 * Destroy an internal thread object.
143 *
144 * @note The mutex of this thread object has to be locked, it gets unlocked
145 * automatically.
146 */
147 static void thread_destroy(private_thread_t *this)
148 {
149 if (!this->terminated || !this->detached_or_joined)
150 {
151 this->mutex->unlock(this->mutex);
152 return;
153 }
154 this->cleanup_handlers->destroy(this->cleanup_handlers);
155 this->mutex->unlock(this->mutex);
156 this->mutex->destroy(this->mutex);
157 free(this);
158 }
159
160 METHOD(thread_t, cancel, void,
161 private_thread_t *this)
162 {
163 this->mutex->lock(this->mutex);
164 if (pthread_equal(this->thread_id, pthread_self()))
165 {
166 this->mutex->unlock(this->mutex);
167 DBG1(DBG_LIB, "!!! CANNOT CANCEL CURRENT THREAD !!!");
168 return;
169 }
170 #ifdef HAVE_PTHREAD_CANCEL
171 pthread_cancel(this->thread_id);
172 #else
173 pthread_kill(this->thread_id, SIG_CANCEL);
174 #endif /* HAVE_PTHREAD_CANCEL */
175 this->mutex->unlock(this->mutex);
176 }
177
178 METHOD(thread_t, kill_, void,
179 private_thread_t *this, int sig)
180 {
181 this->mutex->lock(this->mutex);
182 if (pthread_equal(this->thread_id, pthread_self()))
183 {
184 /* it might actually be possible to send a signal to pthread_self (there
185 * is an example in raise(3) describing that), the problem is though,
186 * that the thread only returns here after the signal handler has
187 * returned, so depending on the signal, the lock might not get
188 * unlocked. */
189 this->mutex->unlock(this->mutex);
190 DBG1(DBG_LIB, "!!! CANNOT SEND SIGNAL TO CURRENT THREAD !!!");
191 return;
192 }
193 pthread_kill(this->thread_id, sig);
194 this->mutex->unlock(this->mutex);
195 }
196
197 METHOD(thread_t, detach, void,
198 private_thread_t *this)
199 {
200 this->mutex->lock(this->mutex);
201 pthread_detach(this->thread_id);
202 this->detached_or_joined = TRUE;
203 thread_destroy(this);
204 }
205
206 METHOD(thread_t, join, void*,
207 private_thread_t *this)
208 {
209 pthread_t thread_id;
210 void *val;
211
212 this->mutex->lock(this->mutex);
213 if (pthread_equal(this->thread_id, pthread_self()))
214 {
215 this->mutex->unlock(this->mutex);
216 DBG1(DBG_LIB, "!!! CANNOT JOIN CURRENT THREAD !!!");
217 return NULL;
218 }
219 if (this->detached_or_joined)
220 {
221 this->mutex->unlock(this->mutex);
222 DBG1(DBG_LIB, "!!! CANNOT JOIN DETACHED THREAD !!!");
223 return NULL;
224 }
225 thread_id = this->thread_id;
226 this->detached_or_joined = TRUE;
227 if (this->terminated)
228 {
229 /* thread has terminated before the call to join */
230 thread_destroy(this);
231 }
232 else
233 {
234 /* thread_destroy is called when the thread terminates normally */
235 this->mutex->unlock(this->mutex);
236 }
237 pthread_join(thread_id, &val);
238
239 return val;
240 }
241
242 /**
243 * Create an internal thread object.
244 */
245 static private_thread_t *thread_create_internal()
246 {
247 private_thread_t *this;
248
249 INIT(this,
250 .public = {
251 .cancel = _cancel,
252 .kill = _kill_,
253 .detach = _detach,
254 .join = _join,
255 },
256 .cleanup_handlers = linked_list_create(),
257 .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
258 );
259
260 return this;
261 }
262
263 /**
264 * Main cleanup function for threads.
265 */
266 static void thread_cleanup(private_thread_t *this)
267 {
268 cleanup_handler_t *handler;
269 this->mutex->lock(this->mutex);
270 while (this->cleanup_handlers->remove_last(this->cleanup_handlers,
271 (void**)&handler) == SUCCESS)
272 {
273 handler->cleanup(handler->arg);
274 free(handler);
275 }
276 this->terminated = TRUE;
277 thread_destroy(this);
278 }
279
280 /**
281 * Main function wrapper for threads.
282 */
283 static void *thread_main(private_thread_t *this)
284 {
285 void *res;
286
287 current_thread->set(current_thread, this);
288 pthread_cleanup_push((thread_cleanup_t)thread_cleanup, this);
289
290 /* TODO: this is not 100% portable as pthread_t is an opaque type (i.e.
291 * could be of any size, or even a struct) */
292 #ifdef HAVE_GETTID
293 DBG2(DBG_LIB, "created thread %.2d [%u]",
294 this->id, gettid());
295 #elif defined(WIN32)
296 DBG2(DBG_LIB, "created thread %.2d [%p]",
297 this->id, this->thread_id.p);
298 #else
299 DBG2(DBG_LIB, "created thread %.2d [%lx]",
300 this->id, (u_long)this->thread_id);
301 #endif
302
303 res = this->main(this->arg);
304 pthread_cleanup_pop(TRUE);
305
306 return res;
307 }
308
309 /**
310 * Described in header.
311 */
312 thread_t *thread_create(thread_main_t main, void *arg)
313 {
314 private_thread_t *this = thread_create_internal();
315
316 this->main = main;
317 this->arg = arg;
318 id_mutex->lock(id_mutex);
319 this->id = next_id++;
320 id_mutex->unlock(id_mutex);
321
322 if (pthread_create(&this->thread_id, NULL, (void*)thread_main, this) != 0)
323 {
324 DBG1(DBG_LIB, "failed to create thread!");
325 this->mutex->lock(this->mutex);
326 thread_destroy(this);
327 return NULL;
328 }
329
330 return &this->public;
331 }
332
333 /**
334 * Described in header.
335 */
336 thread_t *thread_current()
337 {
338 private_thread_t *this;
339
340 this = (private_thread_t*)current_thread->get(current_thread);
341 if (!this)
342 {
343 this = thread_create_internal();
344
345 id_mutex->lock(id_mutex);
346 this->id = next_id++;
347 id_mutex->unlock(id_mutex);
348
349 current_thread->set(current_thread, (void*)this);
350 }
351 return &this->public;
352 }
353
354 /**
355 * Described in header.
356 */
357 u_int thread_current_id()
358 {
359 private_thread_t *this = (private_thread_t*)thread_current();
360
361 return this ? this->id : 0;
362 }
363
364 /**
365 * Described in header.
366 */
367 void thread_cleanup_push(thread_cleanup_t cleanup, void *arg)
368 {
369 private_thread_t *this = (private_thread_t*)thread_current();
370 cleanup_handler_t *handler;
371
372 INIT(handler,
373 .cleanup = cleanup,
374 .arg = arg,
375 );
376
377 this->mutex->lock(this->mutex);
378 this->cleanup_handlers->insert_last(this->cleanup_handlers, handler);
379 this->mutex->unlock(this->mutex);
380 }
381
382 /**
383 * Described in header.
384 */
385 void thread_cleanup_pop(bool execute)
386 {
387 private_thread_t *this = (private_thread_t*)thread_current();
388 cleanup_handler_t *handler;
389
390 this->mutex->lock(this->mutex);
391 if (this->cleanup_handlers->remove_last(this->cleanup_handlers,
392 (void**)&handler) != SUCCESS)
393 {
394 this->mutex->unlock(this->mutex);
395 DBG1(DBG_LIB, "!!! THREAD CLEANUP ERROR !!!");
396 return;
397 }
398 this->mutex->unlock(this->mutex);
399
400 if (execute)
401 {
402 handler->cleanup(handler->arg);
403 }
404 free(handler);
405 }
406
407 /**
408 * Described in header.
409 */
410 bool thread_cancelability(bool enable)
411 {
412 #ifdef HAVE_PTHREAD_CANCEL
413 int old;
414
415 pthread_setcancelstate(enable ? PTHREAD_CANCEL_ENABLE
416 : PTHREAD_CANCEL_DISABLE, &old);
417
418 return old == PTHREAD_CANCEL_ENABLE;
419 #else
420 sigset_t new, old;
421
422 sigemptyset(&new);
423 sigaddset(&new, SIG_CANCEL);
424 pthread_sigmask(enable ? SIG_UNBLOCK : SIG_BLOCK, &new, &old);
425
426 return sigismember(&old, SIG_CANCEL) == 0;
427 #endif /* HAVE_PTHREAD_CANCEL */
428 }
429
430 /**
431 * Described in header.
432 */
433 void thread_cancellation_point()
434 {
435 bool old = thread_cancelability(TRUE);
436
437 #ifdef HAVE_PTHREAD_CANCEL
438 pthread_testcancel();
439 #endif /* HAVE_PTHREAD_CANCEL */
440 thread_cancelability(old);
441 }
442
443 /**
444 * Described in header.
445 */
446 void thread_exit(void *val)
447 {
448 pthread_exit(val);
449 }
450
451 /**
452 * A dummy thread value that reserved pthread_key_t value "0". A buggy PKCS#11
453 * library mangles this key, without owning it, so we allocate it for them.
454 */
455 static thread_value_t *dummy1;
456
457 /**
458 * Described in header.
459 */
460 void threads_init()
461 {
462 private_thread_t *main_thread = thread_create_internal();
463
464 dummy1 = thread_value_create(NULL);
465
466 next_id = 1;
467 main_thread->id = 0;
468 main_thread->thread_id = pthread_self();
469 current_thread = thread_value_create(NULL);
470 current_thread->set(current_thread, (void*)main_thread);
471 id_mutex = mutex_create(MUTEX_TYPE_DEFAULT);
472
473 #ifndef HAVE_PTHREAD_CANCEL
474 { /* install a signal handler for our custom SIG_CANCEL */
475 struct sigaction action = {
476 .sa_handler = cancel_signal_handler
477 };
478 sigaction(SIG_CANCEL, &action, NULL);
479 }
480 #endif /* HAVE_PTHREAD_CANCEL */
481 }
482
483 /**
484 * Described in header.
485 */
486 void threads_deinit()
487 {
488 private_thread_t *main_thread = (private_thread_t*)thread_current();
489
490 dummy1->destroy(dummy1);
491
492 main_thread->mutex->lock(main_thread->mutex);
493 main_thread->terminated = TRUE;
494 main_thread->detached_or_joined = TRUE;
495 thread_destroy(main_thread);
496 current_thread->destroy(current_thread);
497 id_mutex->destroy(id_mutex);
498 }