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