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