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