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