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