]> git.sur5r.net Git - openldap/blob - libraries/libldap_r/thr_posix.c
New POSIX threads version support. Detects Draft 4,5,6,7,10 (final).
[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 /* These are first defined in Draft 7 */
80 #ifndef PTHREAD_CREATE_JOINABLE
81 #define PTHREAD_CREATE_JOINABLE 0
82 #endif
83
84 #ifndef PTHREAD_CREATE_DETACHED
85 #define PTHREAD_CREATE_DETACHED 1
86 #endif
87
88 int 
89 ldap_pvt_thread_create( ldap_pvt_thread_t * thread,
90         int detach,
91         void *(*start_routine)( void * ),
92         void *arg)
93 {
94         int rtn;
95         pthread_attr_t attr;
96 #if HAVE_PTHREADS > 4
97         pthread_attr_init(&attr);
98 #else
99         pthread_attr_create(&attr);
100 #endif
101
102 #if defined(LDAP_PVT_THREAD_STACK_SIZE) && LDAP_PVT_THREAD_STACK_SIZE > 0
103         /* this should be tunable */
104         pthread_attr_setstacksize( &attr, LDAP_PVT_THREAD_STACK_SIZE );
105 #endif
106
107 #if HAVE_PTHREADS > 4
108         detach = detach ? PTHREAD_CREATE_DETACHED : PTHREAD_CREATE_JOINABLE;
109 #if HAVE_PTHREADS == 6
110         pthread_attr_setdetachstate(&attr, &detach);
111 #else
112         pthread_attr_setdetachstate(&attr, detach);
113 #endif
114 #endif
115         rtn = pthread_create( thread, &attr, start_routine, arg );
116 #if HAVE_PTHREADS > 4
117         pthread_attr_destroy(&attr);
118 #else
119         pthread_attr_delete(&attr);
120         if( detach ) {
121                 pthread_detach( thread );
122         }
123 #endif
124
125 #if HAVE_PTHREADS < 7
126         if ( rtn < 0 ) rtn = errno;
127 #endif
128         return rtn;
129 }
130
131 void 
132 ldap_pvt_thread_exit( void *retval )
133 {
134         pthread_exit( retval );
135 }
136
137 int 
138 ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return )
139 {
140 #if HAVE_PTHREADS < 7
141         void *dummy;
142
143         if (thread_return==NULL)
144           thread_return=&dummy;
145
146         if ( pthread_join( thread, thread_return ) < 0 ) return errno;
147         return 0;
148 #else
149         return pthread_join( thread, thread_return );
150 #endif
151 }
152
153 int 
154 ldap_pvt_thread_kill( ldap_pvt_thread_t thread, int signo )
155 {
156 #if HAVE_PTHREADS > 6
157         return pthread_kill( thread, signo );
158 #elif HAVE_PTHREADS == 6
159         if ( pthread_kill( thread, signo ) < 0 ) return errno;
160         return 0;
161 #else
162         /* pthread package with DCE */
163         if (kill( getpid(), signo )<0)
164                 return errno;
165         return 0;
166 #endif
167 }
168
169 int 
170 ldap_pvt_thread_yield( void )
171 {
172 #if HAVE_PTHREADS == 10
173         return sched_yield();
174
175 #elif defined(_POSIX_THREAD_IS_GNU_PTH)
176         sched_yield();
177         return 0;
178
179 #elif HAVE_THR_YIELD
180         return thr_yield();
181
182 #elif HAVE_PTHREADS == 6
183         pthread_yield(NULL);
184         return 0;
185 #else
186         pthread_yield();
187         return 0;
188 #endif
189 }
190
191 int 
192 ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond )
193 {
194 #if HAVE_PTHREADS < 7
195         if ( pthread_cond_init( cond, LDAP_INT_THREAD_CONDATTR_DEFAULT ) < 0 )
196                 return errno;
197         return 0;
198 #else
199         return pthread_cond_init( cond, LDAP_INT_THREAD_CONDATTR_DEFAULT );
200 #endif
201 }
202
203 int 
204 ldap_pvt_thread_cond_destroy( ldap_pvt_thread_cond_t *cond )
205 {
206 #if HAVE_PTHREADS < 7
207         if ( pthread_cond_destroy( cond ) < 0 ) return errno;
208         return 0;
209 #else
210         return pthread_cond_destroy( cond );
211 #endif
212 }
213         
214 int 
215 ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond )
216 {
217 #if HAVE_PTHREADS < 7
218         if ( pthread_cond_signal( cond ) < 0 ) return errno;
219         return 0;
220 #else
221         return pthread_cond_signal( cond );
222 #endif
223 }
224
225 int
226 ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cond )
227 {
228 #if HAVE_PTHREADS < 7
229         if ( pthread_cond_broadcast( cond ) < 0 ) return errno;
230         return 0;
231 #else
232         return pthread_cond_broadcast( cond );
233 #endif
234 }
235
236 int 
237 ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond, 
238                       ldap_pvt_thread_mutex_t *mutex )
239 {
240 #if HAVE_PTHREADS < 7
241         if ( pthread_cond_wait( cond, mutex ) < 0 ) return errno;
242         return 0;
243 #else
244         return pthread_cond_wait( cond, mutex );
245 #endif
246 }
247
248 int 
249 ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex )
250 {
251 #if HAVE_PTHREADS < 7
252         if ( pthread_mutex_init( mutex, LDAP_INT_THREAD_MUTEXATTR_DEFAULT )<0)
253                 return errno;
254         return 0;
255 #else
256         return pthread_mutex_init( mutex, LDAP_INT_THREAD_MUTEXATTR_DEFAULT );
257 #endif
258 }
259
260 int 
261 ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex )
262 {
263 #if HAVE_PTHREADS < 7
264         if ( pthread_mutex_destroy( mutex ) < 0 ) return errno;
265         return 0;
266 #else
267         return pthread_mutex_destroy( mutex );
268 #endif
269 }
270
271 int 
272 ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex )
273 {
274 #if HAVE_PTHREADS < 7
275         if ( pthread_mutex_lock( mutex ) < 0 ) return errno;
276         return 0;
277 #else
278         return pthread_mutex_lock( mutex );
279 #endif
280 }
281
282 int 
283 ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mutex )
284 {
285 #if HAVE_PTHREADS < 7
286         if ( pthread_mutex_trylock( mutex ) < 0 ) return errno;
287         return 0;
288 #else
289         return pthread_mutex_trylock( mutex );
290 #endif
291 }
292
293 int 
294 ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex )
295 {
296 #if HAVE_PTHREADS < 7
297         if ( pthread_mutex_unlock( mutex ) < 0 ) return errno;
298         return 0;
299 #else
300         return pthread_mutex_unlock( mutex );
301 #endif
302 }
303
304 #ifdef LDAP_THREAD_HAVE_RDWR
305 #ifdef HAVE_PTHREAD_RWLOCK_DESTROY
306 int 
307 ldap_pvt_thread_rdwr_init( ldap_pvt_thread_rdwr_t *rw )
308 {
309 #if HAVE_PTHREADS < 7
310         if ( pthread_rwlock_init( rw, NULL ) < 0 ) return errno;
311         return 0;
312 #else
313         return pthread_rwlock_init( rw, NULL );
314 #endif
315 }
316
317 int 
318 ldap_pvt_thread_rdwr_destroy( ldap_pvt_thread_rdwr_t *rw )
319 {
320 #if HAVE_PTHREADS < 7
321         if ( pthread_rwlock_destroy( rw ) < 0 ) return errno;
322         return 0;
323 #else
324         return pthread_rwlock_destroy( rw );
325 #endif
326 }
327
328 int ldap_pvt_thread_rdwr_rlock( ldap_pvt_thread_rdwr_t *rw )
329 {
330 #if HAVE_PTHREADS < 7
331         if ( pthread_rwlock_rdlock( rw ) < 0 ) return errno;
332         return 0;
333 #else
334         return pthread_rwlock_rdlock( rw );
335 #endif
336 }
337
338 int ldap_pvt_thread_rdwr_rtrylock( ldap_pvt_thread_rdwr_t *rw )
339 {
340 #if HAVE_PTHREADS < 7
341         if ( pthread_rwlock_tryrdlock( rw ) < 0 ) return errno;
342         return 0;
343 #else
344         return pthread_rwlock_tryrdlock( rw );
345 #endif
346 }
347
348 int ldap_pvt_thread_rdwr_runlock( ldap_pvt_thread_rdwr_t *rw )
349 {
350 #if HAVE_PTHREADS < 7
351         if ( pthread_rwlock_unlock( rw ) < 0 ) return errno;
352         return 0;
353 #else
354         return pthread_rwlock_unlock( rw );
355 #endif
356 }
357
358 int ldap_pvt_thread_rdwr_wlock( ldap_pvt_thread_rdwr_t *rw )
359 {
360 #if HAVE_PTHREADS < 7
361         if ( pthread_rwlock_wrlock( rw ) < 0 ) return errno;
362         return 0;
363 #else
364         return pthread_rwlock_wrlock( rw );
365 #endif
366 }
367
368 int ldap_pvt_thread_rdwr_wtrylock( ldap_pvt_thread_rdwr_t *rw )
369 {
370 #if HAVE_PTHREADS < 7
371         if ( pthread_rwlock_trywrlock( rw ) < 0 ) return errno;
372         return 0;
373 #else
374         return pthread_rwlock_trywrlock( rw );
375 #endif
376 }
377
378 int ldap_pvt_thread_rdwr_wunlock( ldap_pvt_thread_rdwr_t *rw )
379 {
380 #if HAVE_PTHREADS < 7
381         if ( pthread_rwlock_unlock( rw ) < 0 ) return errno;
382         return 0;
383 #else
384         return pthread_rwlock_unlock( rw );
385 #endif
386 }
387
388 #endif /* HAVE_PTHREAD_RDLOCK_DESTROY */
389 #endif /* LDAP_THREAD_HAVE_RDWR */
390 #endif /* HAVE_PTHREADS */
391