Create a dummy pthread key for value "0", as some buggy PKCS#11 libraries mangle it
[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 #ifndef HAVE_PTHREAD_CANCEL
118 /* if pthread_cancel is not available, we emulate it using a signal */
119 #define SIG_CANCEL (SIGRTMIN+7)
120
121 /* the signal handler for SIG_CANCEL uses pthread_exit to terminate the
122 * "cancelled" thread */
123 static void cancel_signal_handler(int sig)
124 {
125 pthread_exit(NULL);
126 }
127 #endif
128
129
130 /**
131 * Destroy an internal thread object.
132 *
133 * @note The mutex of this thread object has to be locked, it gets unlocked
134 * automatically.
135 */
136 static void thread_destroy(private_thread_t *this)
137 {
138 if (!this->terminated || !this->detached_or_joined)
139 {
140 this->mutex->unlock(this->mutex);
141 return;
142 }
143 this->cleanup_handlers->destroy(this->cleanup_handlers);
144 this->mutex->unlock(this->mutex);
145 this->mutex->destroy(this->mutex);
146 sem_destroy(&this->created);
147 free(this);
148 }
149
150 METHOD(thread_t, cancel, void,
151 private_thread_t *this)
152 {
153 this->mutex->lock(this->mutex);
154 if (pthread_equal(this->thread_id, pthread_self()))
155 {
156 this->mutex->unlock(this->mutex);
157 DBG1(DBG_LIB, "!!! CANNOT CANCEL CURRENT THREAD !!!");
158 return;
159 }
160 #ifdef HAVE_PTHREAD_CANCEL
161 pthread_cancel(this->thread_id);
162 #else
163 pthread_kill(this->thread_id, SIG_CANCEL);
164 #endif /* HAVE_PTHREAD_CANCEL */
165 this->mutex->unlock(this->mutex);
166 }
167
168 METHOD(thread_t, kill_, void,
169 private_thread_t *this, int sig)
170 {
171 this->mutex->lock(this->mutex);
172 if (pthread_equal(this->thread_id, pthread_self()))
173 {
174 /* it might actually be possible to send a signal to pthread_self (there
175 * is an example in raise(3) describing that), the problem is though,
176 * that the thread only returns here after the signal handler has
177 * returned, so depending on the signal, the lock might not get
178 * unlocked. */
179 this->mutex->unlock(this->mutex);
180 DBG1(DBG_LIB, "!!! CANNOT SEND SIGNAL TO CURRENT THREAD !!!");
181 return;
182 }
183 pthread_kill(this->thread_id, sig);
184 this->mutex->unlock(this->mutex);
185 }
186
187 METHOD(thread_t, detach, void,
188 private_thread_t *this)
189 {
190 this->mutex->lock(this->mutex);
191 pthread_detach(this->thread_id);
192 this->detached_or_joined = TRUE;
193 thread_destroy(this);
194 }
195
196 METHOD(thread_t, join, void*,
197 private_thread_t *this)
198 {
199 pthread_t thread_id;
200 void *val;
201
202 this->mutex->lock(this->mutex);
203 if (pthread_equal(this->thread_id, pthread_self()))
204 {
205 this->mutex->unlock(this->mutex);
206 DBG1(DBG_LIB, "!!! CANNOT JOIN CURRENT THREAD !!!");
207 return NULL;
208 }
209 if (this->detached_or_joined)
210 {
211 this->mutex->unlock(this->mutex);
212 DBG1(DBG_LIB, "!!! CANNOT JOIN DETACHED THREAD !!!");
213 return NULL;
214 }
215 thread_id = this->thread_id;
216 this->detached_or_joined = TRUE;
217 if (this->terminated)
218 {
219 /* thread has terminated before the call to join */
220 thread_destroy(this);
221 }
222 else
223 {
224 /* thread_destroy is called when the thread terminates normally */
225 this->mutex->unlock(this->mutex);
226 }
227 pthread_join(thread_id, &val);
228
229 return val;
230 }
231
232 /**
233 * Create an internal thread object.
234 */
235 static private_thread_t *thread_create_internal()
236 {
237 private_thread_t *this;
238
239 INIT(this,
240 .public = {
241 .cancel = _cancel,
242 .kill = _kill_,
243 .detach = _detach,
244 .join = _join,
245 },
246 .cleanup_handlers = linked_list_create(),
247 .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
248 );
249 sem_init(&this->created, FALSE, 0);
250
251 return this;
252 }
253
254 /**
255 * Main cleanup function for threads.
256 */
257 static void thread_cleanup(private_thread_t *this)
258 {
259 cleanup_handler_t *handler;
260 this->mutex->lock(this->mutex);
261 while (this->cleanup_handlers->remove_last(this->cleanup_handlers,
262 (void**)&handler) == SUCCESS)
263 {
264 handler->cleanup(handler->arg);
265 free(handler);
266 }
267 this->terminated = TRUE;
268 thread_destroy(this);
269 }
270
271 /**
272 * Main function wrapper for threads.
273 */
274 static void *thread_main(private_thread_t *this)
275 {
276 void *res;
277
278 sem_wait(&this->created);
279 current_thread->set(current_thread, this);
280 pthread_cleanup_push((thread_cleanup_t)thread_cleanup, this);
281 res = this->main(this->arg);
282 pthread_cleanup_pop(TRUE);
283
284 return res;
285 }
286
287 /**
288 * Described in header.
289 */
290 thread_t *thread_create(thread_main_t main, void *arg)
291 {
292 private_thread_t *this = thread_create_internal();
293
294 this->main = main;
295 this->arg = arg;
296 if (pthread_create(&this->thread_id, NULL, (void*)thread_main, this) != 0)
297 {
298 DBG1(DBG_LIB, "failed to create thread!");
299 this->mutex->lock(this->mutex);
300 thread_destroy(this);
301 return NULL;
302 }
303 id_mutex->lock(id_mutex);
304 this->id = next_id++;
305 id_mutex->unlock(id_mutex);
306 sem_post(&this->created);
307
308 return &this->public;
309 }
310
311 /**
312 * Described in header.
313 */
314 thread_t *thread_current()
315 {
316 return current_thread->get(current_thread);
317 }
318
319 /**
320 * Described in header.
321 */
322 u_int thread_current_id()
323 {
324 private_thread_t *this = (private_thread_t*)thread_current();
325
326 return this ? this->id : 0;
327 }
328
329 /**
330 * Described in header.
331 */
332 void thread_cleanup_push(thread_cleanup_t cleanup, void *arg)
333 {
334 private_thread_t *this = (private_thread_t*)thread_current();
335 cleanup_handler_t *handler;
336
337 INIT(handler,
338 .cleanup = cleanup,
339 .arg = arg,
340 );
341
342 this->mutex->lock(this->mutex);
343 this->cleanup_handlers->insert_last(this->cleanup_handlers, handler);
344 this->mutex->unlock(this->mutex);
345 }
346
347 /**
348 * Described in header.
349 */
350 void thread_cleanup_pop(bool execute)
351 {
352 private_thread_t *this = (private_thread_t*)thread_current();
353 cleanup_handler_t *handler;
354
355 this->mutex->lock(this->mutex);
356 if (this->cleanup_handlers->remove_last(this->cleanup_handlers,
357 (void**)&handler) != SUCCESS)
358 {
359 this->mutex->unlock(this->mutex);
360 DBG1(DBG_LIB, "!!! THREAD CLEANUP ERROR !!!");
361 return;
362 }
363 this->mutex->unlock(this->mutex);
364
365 if (execute)
366 {
367 handler->cleanup(handler->arg);
368 }
369 free(handler);
370 }
371
372 /**
373 * Described in header.
374 */
375 bool thread_cancelability(bool enable)
376 {
377 #ifdef HAVE_PTHREAD_CANCEL
378 int old;
379
380 pthread_setcancelstate(enable ? PTHREAD_CANCEL_ENABLE
381 : PTHREAD_CANCEL_DISABLE, &old);
382
383 return old == PTHREAD_CANCEL_ENABLE;
384 #else
385 sigset_t new, old;
386
387 sigemptyset(&new);
388 sigaddset(&new, SIG_CANCEL);
389 pthread_sigmask(enable ? SIG_UNBLOCK : SIG_BLOCK, &new, &old);
390
391 return sigismember(&old, SIG_CANCEL) == 0;
392 #endif /* HAVE_PTHREAD_CANCEL */
393 }
394
395 /**
396 * Described in header.
397 */
398 void thread_cancellation_point()
399 {
400 bool old = thread_cancelability(TRUE);
401
402 #ifdef HAVE_PTHREAD_CANCEL
403 pthread_testcancel();
404 #endif /* HAVE_PTHREAD_CANCEL */
405 thread_cancelability(old);
406 }
407
408 /**
409 * Described in header.
410 */
411 void thread_exit(void *val)
412 {
413 pthread_exit(val);
414 }
415
416 /**
417 * A dummy thread value that reserved pthread_key_t value "0". A buggy PKCS#11
418 * library mangles this key, without owning it, so we allocate it for them.
419 */
420 static thread_value_t *dummy1;
421
422 /**
423 * Described in header.
424 */
425 void threads_init()
426 {
427 private_thread_t *main_thread = thread_create_internal();
428
429 dummy1 = thread_value_create(NULL);
430
431 main_thread->id = 0;
432 main_thread->thread_id = pthread_self();
433 current_thread = thread_value_create(NULL);
434 current_thread->set(current_thread, (void*)main_thread);
435 id_mutex = mutex_create(MUTEX_TYPE_DEFAULT);
436
437 #ifndef HAVE_PTHREAD_CANCEL
438 { /* install a signal handler for our custom SIG_CANCEL */
439 struct sigaction action = {
440 .sa_handler = cancel_signal_handler
441 };
442 sigaction(SIG_CANCEL, &action, NULL);
443 }
444 #endif /* HAVE_PTHREAD_CANCEL */
445 }
446
447 /**
448 * Described in header.
449 */
450 void threads_deinit()
451 {
452 private_thread_t *main_thread = (private_thread_t*)thread_current();
453
454 dummy1->destroy(dummy1);
455
456 main_thread->mutex->lock(main_thread->mutex);
457 thread_destroy(main_thread);
458 current_thread->destroy(current_thread);
459 id_mutex->destroy(id_mutex);
460 }
461