Added SILC Thread Queue API
[silc.git] / lib / silcutil / beos / silcbeosthread.c
1 /*
2
3   silcbeosthread.c 
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2002 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 /* I used Apache's APR code as a reference here. */
20 /* $Id$ */
21
22 /* XXX This leaks memory. Perhaps the SilcThread API should be changed
23    since the silc_thread_self() causes that BeOS and OS/2 is hard to
24    do to support this SilcThread API */
25
26 #include "silc.h"
27
28 #ifdef SILC_THREADS
29
30 /* Thread structure for BeOS */
31 typedef struct {
32   thread_id thread;
33   SilcThreadStart start_func;
34   void *context;
35   SilcBool waitable;
36 } *SilcBeosThread;
37
38 /* Actual routine that is called by BeOS when the thread is created.
39    We will call the start_func from here. */
40
41 static void *silc_thread_beos_start(void *context)
42 {
43   SilcBeosThread thread = (SilcBeosThread)context;
44   return (*thread->start_func)(thread->context);
45 }
46
47 #endif
48
49 SilcThread silc_thread_create(SilcThreadStart start_func, void *context,
50                               SilcBool waitable)
51 {
52 #ifdef SILC_THREADS
53   int ret;
54   SilcBeosThread thread = silc_calloc(1, sizeof(*thread));
55   if (!thread)
56     return NULL;
57
58   thread->start_func = start_func;
59   thread->context = context;
60   thread->waitable = waitable;
61
62   /* Create the thread, and run it */
63   thread->thread = spawn_thread((thread_func)silc_thread_beos_start,
64                                 B_NORMAL_PRIORITY, thread);
65   ret = resume_thread(thread->thread);
66   if (ret < B_NO_ERROR) {
67     SILC_LOG_ERROR(("Could not create new thread"));
68     silc_free(thread);
69     return NULL;
70   }
71
72   return (SilcThread)thread->thread;
73 #else
74   /* Call thread callback immediately */
75   (*start_func)(context);
76   return NULL;
77 #endif
78 }
79
80 void silc_thread_exit(void *exit_value)
81 {
82 #ifdef SILC_THREADS
83   exit_thread((status_t)exit_value);
84 #endif
85 }
86
87 SilcThread silc_thread_self(void)
88 {
89 #ifdef SILC_THREADS
90   return (SilcThread)find_thread(NULL);
91 #else
92   return NULL;
93 #endif
94 }
95
96 SilcBool silc_thread_wait(SilcThread thread, void **exit_value)
97 {
98 #ifdef SILC_THREADS
99   status_t ret, retval;
100
101   ret = wait_for_thread((thread_id)thread, &retval);
102   if (ret == B_NO_ERROR) {
103     if (exit_value)
104       *exit_value = retval;
105     return TRUE;
106   }
107
108   return FALSE;
109 #else
110   return FALSE;
111 #endif
112 }