]> git.sur5r.net Git - openldap/blob - libraries/libldap_r/thr_posix.c
a2812302915c15f3b1f9aaa90cf2a9a0fe0d39c6
[openldap] / libraries / libldap_r / thr_posix.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-2002 The OpenLDAP Foundation, Redwood City, California, USA
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms are permitted only
7  * as authorized by the OpenLDAP Public License.  A copy of this
8  * license is available at http://www.OpenLDAP.org/license.html or
9  * in file LICENSE in the top-level directory of the distribution.
10  */
11
12 /* thr_posix.c - wrapper around posix and posixish thread implementations.
13  */
14
15 #include "portable.h"
16
17 #if defined( HAVE_PTHREADS )
18
19 #include <ac/errno.h>
20
21 #include "ldap_pvt_thread.h"
22
23
24 #if HAVE_PTHREADS == 4
25 #  define LDAP_INT_THREAD_ATTR_DEFAULT          pthread_attr_default
26 #  define LDAP_INT_THREAD_CONDATTR_DEFAULT      pthread_condattr_default
27 #  define LDAP_INT_THREAD_MUTEXATTR_DEFAULT     pthread_mutexattr_default
28 #else
29 #  define LDAP_INT_THREAD_ATTR_DEFAULT          NULL
30 #  define LDAP_INT_THREAD_CONDATTR_DEFAULT      NULL
31 #  define LDAP_INT_THREAD_MUTEXATTR_DEFAULT     NULL
32 #endif
33
34
35 int
36 ldap_int_thread_initialize( void )
37 {
38         return 0;
39 }
40
41 int
42 ldap_int_thread_destroy( void )
43 {
44 #ifdef HAVE_PTHREAD_KILL_OTHER_THREADS_NP
45         /* LinuxThreads: kill clones */
46         pthread_kill_other_threads_np();
47 #endif
48         return 0;
49 }
50
51 #ifdef LDAP_THREAD_HAVE_SETCONCURRENCY
52 int
53 ldap_pvt_thread_set_concurrency(int n)
54 {
55 #ifdef HAVE_PTHREAD_SETCONCURRENCY
56         return pthread_setconcurrency( n );
57 #elif HAVE_THR_SETCONCURRENCY
58         return thr_setconcurrency( n );
59 #else
60         return 0;
61 #endif
62 }
63 #endif
64
65 #ifdef LDAP_THREAD_HAVE_GETCONCURRENCY
66 int
67 ldap_pvt_thread_get_concurrency(void)
68 {
69 #ifdef HAVE_PTHREAD_GETCONCURRENCY
70         return pthread_getconcurrency();
71 #elif HAVE_THR_GETCONCURRENCY
72         return thr_getconcurrency();
73 #else
74         return 0;
75 #endif
76 }
77 #endif
78
79 /* detachstate appeared in Draft 6, but without manifest constants.
80  * in Draft 7 they were called PTHREAD_CREATE_UNDETACHED and ...DETACHED.
81  * in Draft 8 on, ...UNDETACHED became ...JOINABLE.
82  */
83 #ifndef PTHREAD_CREATE_JOINABLE
84 #ifdef PTHREAD_CREATE_UNDETACHED
85 #define PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED
86 #else
87 #define PTHREAD_CREATE_JOINABLE 0
88 #endif
89 #endif
90
91 #ifndef PTHREAD_CREATE_DETACHED
92 #define PTHREAD_CREATE_DETACHED 1
93 #endif
94
95 int 
96 ldap_pvt_thread_create( ldap_pvt_thread_t * thread,
97         int detach,
98         void *(*start_routine)( void * ),
99         void *arg)
100 {
101         int rtn;
102         pthread_attr_t attr;
103
104 /* Always create the thread attrs, so we can set stacksize if we need to */
105 #if HAVE_PTHREADS > 4
106         pthread_attr_init(&attr);
107 #else
108         pthread_attr_create(&attr);
109 #endif
110
111 #if defined(LDAP_PVT_THREAD_STACK_SIZE) && LDAP_PVT_THREAD_STACK_SIZE > 0
112         /* this should be tunable */
113         pthread_attr_setstacksize( &attr, LDAP_PVT_THREAD_STACK_SIZE );
114 #endif
115
116 #if HAVE_PTHREADS > 5
117         detach = detach ? PTHREAD_CREATE_DETACHED : PTHREAD_CREATE_JOINABLE;
118 #if HAVE_PTHREADS == 6
119         pthread_attr_setdetachstate(&attr, &detach);
120 #else
121         pthread_attr_setdetachstate(&attr, detach);
122 #endif
123 #endif
124         rtn = pthread_create( thread, &attr, start_routine, arg );
125 #if HAVE_PTHREADS > 4
126         pthread_attr_destroy(&attr);
127 #else
128         pthread_attr_delete(&attr);
129 #endif
130 #if HAVE_PTHREADS < 6
131         if( detach ) {
132                 pthread_detach( thread );
133         }
134 #endif
135
136 #if HAVE_PTHREADS < 7
137         if ( rtn < 0 ) rtn = errno;
138 #endif
139         return rtn;
140 }
141
142 void 
143 ldap_pvt_thread_exit( void *retval )
144 {
145         pthread_exit( retval );
146 }
147
148 int 
149 ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return )
150 {
151 #if HAVE_PTHREADS < 7
152         void *dummy;
153
154         if (thread_return==NULL)
155           thread_return=&dummy;
156
157         if ( pthread_join( thread, thread_return ) < 0 ) return errno;
158         return 0;
159 #else
160         return pthread_join( thread, thread_return );
161 #endif
162 }
163
164 int 
165 ldap_pvt_thread_kill( ldap_pvt_thread_t thread, int signo )
166 {
167 #if HAVE_PTHREADS > 6
168         return pthread_kill( thread, signo );
169 #elif HAVE_PTHREADS > 4
170         if ( pthread_kill( thread, signo ) < 0 ) return errno;
171         return 0;
172 #else
173         /* pthread package with DCE */
174         if (kill( getpid(), signo )<0)
175                 return errno;
176         return 0;
177 #endif
178 }
179
180 int 
181 ldap_pvt_thread_yield( void )
182 {
183 #if HAVE_PTHREADS == 10
184         return sched_yield();
185
186 #elif defined(_POSIX_THREAD_IS_GNU_PTH)
187         sched_yield();
188         return 0;
189
190 #elif HAVE_THR_YIELD
191         return thr_yield();
192
193 #elif HAVE_PTHREADS == 6
194         pthread_yield(NULL);
195         return 0;
196 #else
197         pthread_yield();
198         return 0;
199 #endif
200 }
201
202 int 
203 ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond )
204 {
205 #if HAVE_PTHREADS < 7
206         if ( pthread_cond_init( cond, LDAP_INT_THREAD_CONDATTR_DEFAULT ) < 0 )
207                 return errno;
208         return 0;
209 #else
210         return pthread_cond_init( cond, LDAP_INT_THREAD_CONDATTR_DEFAULT );
211 #endif
212 }
213
214 int 
215 ldap_pvt_thread_cond_destroy( ldap_pvt_thread_cond_t *cond )
216 {
217 #if HAVE_PTHREADS < 7
218         if ( pthread_cond_destroy( cond ) < 0 ) return errno;
219         return 0;
220 #else
221         return pthread_cond_destroy( cond );
222 #endif
223 }
224         
225 int 
226 ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond )
227 {
228 #if HAVE_PTHREADS < 7
229         if ( pthread_cond_signal( cond ) < 0 ) return errno;
230         return 0;
231 #else
232         return pthread_cond_signal( cond );
233 #endif
234 }
235
236 int
237 ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cond )
238 {
239 #if HAVE_PTHREADS < 7
240         if ( pthread_cond_broadcast( cond ) < 0 ) return errno;
241         return 0;
242 #else
243         return pthread_cond_broadcast( cond );
244 #endif
245 }
246
247 int 
248 ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond, 
249                       ldap_pvt_thread_mutex_t *mutex )
250 {
251 #if HAVE_PTHREADS < 7
252         if ( pthread_cond_wait( cond, mutex ) < 0 ) return errno;
253         return 0;
254 #else
255         return pthread_cond_wait( cond, mutex );
256 #endif
257 }
258
259 int 
260 ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex )
261 {
262 #if HAVE_PTHREADS < 7
263         if ( pthread_mutex_init( mutex, LDAP_INT_THREAD_MUTEXATTR_DEFAULT )<0)
264                 return errno;
265         return 0;
266 #else
267         return pthread_mutex_init( mutex, LDAP_INT_THREAD_MUTEXATTR_DEFAULT );
268 #endif
269 }
270
271 int 
272 ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex )
273 {
274 #if HAVE_PTHREADS < 7
275         if ( pthread_mutex_destroy( mutex ) < 0 ) return errno;
276         return 0;
277 #else
278         return pthread_mutex_destroy( mutex );
279 #endif
280 }
281
282 int 
283 ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex )
284 {
285 #if HAVE_PTHREADS < 7
286         if ( pthread_mutex_lock( mutex ) < 0 ) return errno;
287         return 0;
288 #else
289         return pthread_mutex_lock( mutex );
290 #endif
291 }
292
293 int 
294 ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mutex )
295 {
296 #if HAVE_PTHREADS < 7
297         if ( pthread_mutex_trylock( mutex ) < 0 ) return errno;
298         return 0;
299 #else
300         return pthread_mutex_trylock( mutex );
301 #endif
302 }
303
304 int 
305 ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex )
306 {
307 #if HAVE_PTHREADS < 7
308         if ( pthread_mutex_unlock( mutex ) < 0 ) return errno;
309         return 0;
310 #else
311         return pthread_mutex_unlock( mutex );
312 #endif
313 }
314
315 #ifdef LDAP_THREAD_HAVE_RDWR
316 #ifdef HAVE_PTHREAD_RWLOCK_DESTROY
317 int 
318 ldap_pvt_thread_rdwr_init( ldap_pvt_thread_rdwr_t *rw )
319 {
320 #if HAVE_PTHREADS < 7
321         if ( pthread_rwlock_init( rw, NULL ) < 0 ) return errno;
322         return 0;
323 #else
324         return pthread_rwlock_init( rw, NULL );
325 #endif
326 }
327
328 int 
329 ldap_pvt_thread_rdwr_destroy( ldap_pvt_thread_rdwr_t *rw )
330 {
331 #if HAVE_PTHREADS < 7
332         if ( pthread_rwlock_destroy( rw ) < 0 ) return errno;
333         return 0;
334 #else
335         return pthread_rwlock_destroy( rw );
336 #endif
337 }
338
339 int ldap_pvt_thread_rdwr_rlock( ldap_pvt_thread_rdwr_t *rw )
340 {
341 #if HAVE_PTHREADS < 7
342         if ( pthread_rwlock_rdlock( rw ) < 0 ) return errno;
343         return 0;
344 #else
345         return pthread_rwlock_rdlock( rw );
346 #endif
347 }
348
349 int ldap_pvt_thread_rdwr_rtrylock( ldap_pvt_thread_rdwr_t *rw )
350 {
351 #if HAVE_PTHREADS < 7
352         if ( pthread_rwlock_tryrdlock( rw ) < 0 ) return errno;
353         return 0;
354 #else
355         return pthread_rwlock_tryrdlock( rw );
356 #endif
357 }
358
359 int ldap_pvt_thread_rdwr_runlock( ldap_pvt_thread_rdwr_t *rw )
360 {
361 #if HAVE_PTHREADS < 7
362         if ( pthread_rwlock_unlock( rw ) < 0 ) return errno;
363         return 0;
364 #else
365         return pthread_rwlock_unlock( rw );
366 #endif
367 }
368
369 int ldap_pvt_thread_rdwr_wlock( ldap_pvt_thread_rdwr_t *rw )
370 {
371 #if HAVE_PTHREADS < 7
372         if ( pthread_rwlock_wrlock( rw ) < 0 ) return errno;
373         return 0;
374 #else
375         return pthread_rwlock_wrlock( rw );
376 #endif
377 }
378
379 int ldap_pvt_thread_rdwr_wtrylock( ldap_pvt_thread_rdwr_t *rw )
380 {
381 #if HAVE_PTHREADS < 7
382         if ( pthread_rwlock_trywrlock( rw ) < 0 ) return errno;
383         return 0;
384 #else
385         return pthread_rwlock_trywrlock( rw );
386 #endif
387 }
388
389 int ldap_pvt_thread_rdwr_wunlock( ldap_pvt_thread_rdwr_t *rw )
390 {
391 #if HAVE_PTHREADS < 7
392         if ( pthread_rwlock_unlock( rw ) < 0 ) return errno;
393         return 0;
394 #else
395         return pthread_rwlock_unlock( rw );
396 #endif
397 }
398
399 #endif /* HAVE_PTHREAD_RDLOCK_DESTROY */
400 #endif /* LDAP_THREAD_HAVE_RDWR */
401 #endif /* HAVE_PTHREADS */
402