]> git.sur5r.net Git - openldap/blob - libraries/libldap_r/thr_posix.c
dfeb48f63f09266b68899f36bc30930b733390a5
[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 < 6
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 > 5
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 > 5
126         pthread_attr_destroy(&attr);
127 #else
128         pthread_attr_delete(&attr);
129         if( detach ) {
130                 pthread_detach( thread );
131         }
132 #endif
133
134 #if HAVE_PTHREADS < 7
135         if ( rtn < 0 ) rtn = errno;
136 #endif
137         return rtn;
138 }
139
140 void 
141 ldap_pvt_thread_exit( void *retval )
142 {
143         pthread_exit( retval );
144 }
145
146 int 
147 ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return )
148 {
149 #if HAVE_PTHREADS < 7
150         void *dummy;
151
152         if (thread_return==NULL)
153           thread_return=&dummy;
154
155         if ( pthread_join( thread, thread_return ) < 0 ) return errno;
156         return 0;
157 #else
158         return pthread_join( thread, thread_return );
159 #endif
160 }
161
162 int 
163 ldap_pvt_thread_kill( ldap_pvt_thread_t thread, int signo )
164 {
165 #if ( HAVE_PTHREAD_KILL && HAVE_PTHREADS > 6 )
166         /* MacOS 10.1 is detected as v10 but has no pthread_kill() */
167         return pthread_kill( thread, signo );
168 #elif ( HAVE_PTHREAD_KILL && HAVE_PTHREADS > 4 )
169         if ( pthread_kill( thread, signo ) < 0 ) return errno;
170         return 0;
171 #else
172         /* pthread package with DCE */
173         if (kill( getpid(), signo )<0)
174                 return errno;
175         return 0;
176 #endif
177 }
178
179 int 
180 ldap_pvt_thread_yield( void )
181 {
182 #if HAVE_PTHREADS == 10
183         return sched_yield();
184
185 #elif defined(_POSIX_THREAD_IS_GNU_PTH)
186         sched_yield();
187         return 0;
188
189 #elif HAVE_THR_YIELD
190         return thr_yield();
191
192 #elif HAVE_PTHREADS == 6
193         pthread_yield(NULL);
194         return 0;
195 #else
196         pthread_yield();
197         return 0;
198 #endif
199 }
200
201 int 
202 ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond )
203 {
204 #if HAVE_PTHREADS < 7
205         if ( pthread_cond_init( cond, LDAP_INT_THREAD_CONDATTR_DEFAULT ) < 0 )
206                 return errno;
207         return 0;
208 #else
209         return pthread_cond_init( cond, LDAP_INT_THREAD_CONDATTR_DEFAULT );
210 #endif
211 }
212
213 int 
214 ldap_pvt_thread_cond_destroy( ldap_pvt_thread_cond_t *cond )
215 {
216 #if HAVE_PTHREADS < 7
217         if ( pthread_cond_destroy( cond ) < 0 ) return errno;
218         return 0;
219 #else
220         return pthread_cond_destroy( cond );
221 #endif
222 }
223         
224 int 
225 ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond )
226 {
227 #if HAVE_PTHREADS < 7
228         if ( pthread_cond_signal( cond ) < 0 ) return errno;
229         return 0;
230 #else
231         return pthread_cond_signal( cond );
232 #endif
233 }
234
235 int
236 ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cond )
237 {
238 #if HAVE_PTHREADS < 7
239         if ( pthread_cond_broadcast( cond ) < 0 ) return errno;
240         return 0;
241 #else
242         return pthread_cond_broadcast( cond );
243 #endif
244 }
245
246 int 
247 ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond, 
248                       ldap_pvt_thread_mutex_t *mutex )
249 {
250 #if HAVE_PTHREADS < 7
251         if ( pthread_cond_wait( cond, mutex ) < 0 ) return errno;
252         return 0;
253 #else
254         return pthread_cond_wait( cond, mutex );
255 #endif
256 }
257
258 int 
259 ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex )
260 {
261 #if HAVE_PTHREADS < 7
262         if ( pthread_mutex_init( mutex, LDAP_INT_THREAD_MUTEXATTR_DEFAULT )<0)
263                 return errno;
264         return 0;
265 #else
266         return pthread_mutex_init( mutex, LDAP_INT_THREAD_MUTEXATTR_DEFAULT );
267 #endif
268 }
269
270 int 
271 ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex )
272 {
273 #if HAVE_PTHREADS < 7
274         if ( pthread_mutex_destroy( mutex ) < 0 ) return errno;
275         return 0;
276 #else
277         return pthread_mutex_destroy( mutex );
278 #endif
279 }
280
281 int 
282 ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex )
283 {
284 #if HAVE_PTHREADS < 7
285         if ( pthread_mutex_lock( mutex ) < 0 ) return errno;
286         return 0;
287 #else
288         return pthread_mutex_lock( mutex );
289 #endif
290 }
291
292 int 
293 ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mutex )
294 {
295 #if HAVE_PTHREADS < 7
296         if ( pthread_mutex_trylock( mutex ) < 0 ) return errno;
297         return 0;
298 #else
299         return pthread_mutex_trylock( mutex );
300 #endif
301 }
302
303 int 
304 ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex )
305 {
306 #if HAVE_PTHREADS < 7
307         if ( pthread_mutex_unlock( mutex ) < 0 ) return errno;
308         return 0;
309 #else
310         return pthread_mutex_unlock( mutex );
311 #endif
312 }
313
314 #ifdef LDAP_THREAD_HAVE_RDWR
315 #ifdef HAVE_PTHREAD_RWLOCK_DESTROY
316 int 
317 ldap_pvt_thread_rdwr_init( ldap_pvt_thread_rdwr_t *rw )
318 {
319 #if HAVE_PTHREADS < 7
320         if ( pthread_rwlock_init( rw, NULL ) < 0 ) return errno;
321         return 0;
322 #else
323         return pthread_rwlock_init( rw, NULL );
324 #endif
325 }
326
327 int 
328 ldap_pvt_thread_rdwr_destroy( ldap_pvt_thread_rdwr_t *rw )
329 {
330 #if HAVE_PTHREADS < 7
331         if ( pthread_rwlock_destroy( rw ) < 0 ) return errno;
332         return 0;
333 #else
334         return pthread_rwlock_destroy( rw );
335 #endif
336 }
337
338 int ldap_pvt_thread_rdwr_rlock( ldap_pvt_thread_rdwr_t *rw )
339 {
340 #if HAVE_PTHREADS < 7
341         if ( pthread_rwlock_rdlock( rw ) < 0 ) return errno;
342         return 0;
343 #else
344         return pthread_rwlock_rdlock( rw );
345 #endif
346 }
347
348 int ldap_pvt_thread_rdwr_rtrylock( ldap_pvt_thread_rdwr_t *rw )
349 {
350 #if HAVE_PTHREADS < 7
351         if ( pthread_rwlock_tryrdlock( rw ) < 0 ) return errno;
352         return 0;
353 #else
354         return pthread_rwlock_tryrdlock( rw );
355 #endif
356 }
357
358 int ldap_pvt_thread_rdwr_runlock( ldap_pvt_thread_rdwr_t *rw )
359 {
360 #if HAVE_PTHREADS < 7
361         if ( pthread_rwlock_unlock( rw ) < 0 ) return errno;
362         return 0;
363 #else
364         return pthread_rwlock_unlock( rw );
365 #endif
366 }
367
368 int ldap_pvt_thread_rdwr_wlock( ldap_pvt_thread_rdwr_t *rw )
369 {
370 #if HAVE_PTHREADS < 7
371         if ( pthread_rwlock_wrlock( rw ) < 0 ) return errno;
372         return 0;
373 #else
374         return pthread_rwlock_wrlock( rw );
375 #endif
376 }
377
378 int ldap_pvt_thread_rdwr_wtrylock( ldap_pvt_thread_rdwr_t *rw )
379 {
380 #if HAVE_PTHREADS < 7
381         if ( pthread_rwlock_trywrlock( rw ) < 0 ) return errno;
382         return 0;
383 #else
384         return pthread_rwlock_trywrlock( rw );
385 #endif
386 }
387
388 int ldap_pvt_thread_rdwr_wunlock( ldap_pvt_thread_rdwr_t *rw )
389 {
390 #if HAVE_PTHREADS < 7
391         if ( pthread_rwlock_unlock( rw ) < 0 ) return errno;
392         return 0;
393 #else
394         return pthread_rwlock_unlock( rw );
395 #endif
396 }
397
398 #endif /* HAVE_PTHREAD_RDLOCK_DESTROY */
399 #endif /* LDAP_THREAD_HAVE_RDWR */
400 #endif /* HAVE_PTHREADS */
401