575c54a894a8b8d4f09210b11d8c0ed9cc0d0df9
[silc.git] / lib / silcutil / unix / silcunixthread.c
1 /*
2
3   silcunixthread.c
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2001 Pekka Riikonen
8
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; either version 2 of the License, or
12   (at your option) any later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19 */
20 /* $Id$ */
21
22 #include "silcincludes.h"
23
24 SilcThread silc_thread_create(SilcThreadStart start_func, void *context,
25                               bool waitable)
26 {
27 #ifdef SILC_THREADS
28   pthread_attr_t attr;
29   pthread_t thread;
30   int ret;
31
32   SILC_LOG_DEBUG(("Creating new thread"));
33
34   if (!start_func)
35     return NULL;
36
37   if (pthread_attr_init(&attr)) {
38     SILC_LOG_ERROR(("Thread error: %s", strerror(errno)));
39     return NULL;
40   }
41
42   if (pthread_attr_setdetachstate(&attr,
43                                   waitable ? PTHREAD_CREATE_JOINABLE : 
44                                   PTHREAD_CREATE_DETACHED)) {
45     SILC_LOG_ERROR(("Thread error: %s", strerror(errno)));
46     pthread_attr_destroy(&attr);
47     return NULL;
48   }
49
50   ret = pthread_create(&thread, &attr, (void * (*)(void *))start_func, 
51                        context);
52   if (ret) {
53     SILC_LOG_ERROR(("Thread error: %s", strerror(errno)));
54     pthread_attr_destroy(&attr);
55     return NULL;
56   }
57
58   pthread_attr_destroy(&attr);
59
60   SILC_LOG_DEBUG(("Created thread %p", (SilcThread)thread));
61
62   return (SilcThread)thread;
63 #else
64   /* Call thread callback immediately */
65   (*start_func)(context);
66   return NULL;
67 #endif
68 }
69
70 void silc_thread_exit(void *exit_value)
71 {
72 #ifdef SILC_THREADS
73   pthread_exit(exit_value);
74 #endif
75 }
76
77 SilcThread silc_thread_self(void)
78 {
79 #ifdef SILC_THREADS
80   pthread_t self = pthread_self();
81   return (SilcThread)self;
82 #else
83   return NULL;
84 #endif
85 }
86
87 bool silc_thread_wait(SilcThread thread, void **exit_value)
88 {
89 #ifdef SILC_THREADS
90   SILC_LOG_DEBUG(("Waiting for thread %p", thread));
91   if (!pthread_join(*(pthread_t *)thread, exit_value))
92     return TRUE;
93   return FALSE;
94 #else
95   return FALSE;
96 #endif
97 }