]> git.sur5r.net Git - openldap/blob - libraries/libldap_r/thr_posix.c
Merge remote-tracking branch 'origin/mdb.RE/0.9'
[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-2015 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 #ifdef REPLACE_BROKEN_YIELD
24 #ifndef HAVE_NANOSLEEP
25 #include <ac/socket.h>
26 #endif
27 #include <ac/time.h>
28 #endif
29
30 #include "ldap_pvt_thread.h" /* Get the thread interface */
31 #define LDAP_THREAD_IMPLEMENTATION
32 #define LDAP_THREAD_RDWR_IMPLEMENTATION
33 #include "ldap_thr_debug.h"      /* May rename the symbols defined below */
34 #include <signal.h>                      /* For pthread_kill() */
35
36 extern int ldap_int_stackguard;
37
38 #if HAVE_PTHREADS < 6
39 #  define LDAP_INT_THREAD_ATTR_DEFAULT          pthread_attr_default
40 #  define LDAP_INT_THREAD_CONDATTR_DEFAULT      pthread_condattr_default
41 #  define LDAP_INT_THREAD_MUTEXATTR_DEFAULT     pthread_mutexattr_default
42 #else
43 #  define LDAP_INT_THREAD_ATTR_DEFAULT          NULL
44 #  define LDAP_INT_THREAD_CONDATTR_DEFAULT      NULL
45 #  define LDAP_INT_THREAD_MUTEXATTR_DEFAULT NULL
46 #endif
47
48 #ifdef LDAP_THREAD_DEBUG
49 #  if defined LDAP_INT_THREAD_MUTEXATTR /* May be defined in CPPFLAGS */
50 #  elif defined HAVE_PTHREAD_KILL_OTHER_THREADS_NP
51          /* LinuxThreads hack */
52 #    define LDAP_INT_THREAD_MUTEXATTR   PTHREAD_MUTEX_ERRORCHECK_NP
53 #  else
54 #    define LDAP_INT_THREAD_MUTEXATTR   PTHREAD_MUTEX_ERRORCHECK
55 #  endif
56 static pthread_mutexattr_t mutex_attr;
57 #  undef  LDAP_INT_THREAD_MUTEXATTR_DEFAULT
58 #  define LDAP_INT_THREAD_MUTEXATTR_DEFAULT &mutex_attr
59 #endif
60
61 #if HAVE_PTHREADS < 7
62 #define ERRVAL(val)     ((val) < 0 ? errno : 0)
63 #else
64 #define ERRVAL(val)     (val)
65 #endif
66
67 int
68 ldap_int_thread_initialize( void )
69 {
70 #ifdef LDAP_INT_THREAD_MUTEXATTR
71         pthread_mutexattr_init( &mutex_attr );
72         pthread_mutexattr_settype( &mutex_attr, LDAP_INT_THREAD_MUTEXATTR );
73 #endif
74         return 0;
75 }
76
77 int
78 ldap_int_thread_destroy( void )
79 {
80 #ifdef HAVE_PTHREAD_KILL_OTHER_THREADS_NP
81         /* LinuxThreads: kill clones */
82         pthread_kill_other_threads_np();
83 #endif
84 #ifdef LDAP_INT_THREAD_MUTEXATTR
85         pthread_mutexattr_destroy( &mutex_attr );
86 #endif
87         return 0;
88 }
89
90 #ifdef LDAP_THREAD_HAVE_SETCONCURRENCY
91 int
92 ldap_pvt_thread_set_concurrency(int n)
93 {
94 #ifdef HAVE_PTHREAD_SETCONCURRENCY
95         return pthread_setconcurrency( n );
96 #elif defined(HAVE_THR_SETCONCURRENCY)
97         return thr_setconcurrency( n );
98 #else
99         return 0;
100 #endif
101 }
102 #endif
103
104 #ifdef LDAP_THREAD_HAVE_GETCONCURRENCY
105 int
106 ldap_pvt_thread_get_concurrency(void)
107 {
108 #ifdef HAVE_PTHREAD_GETCONCURRENCY
109         return pthread_getconcurrency();
110 #elif defined(HAVE_THR_GETCONCURRENCY)
111         return thr_getconcurrency();
112 #else
113         return 0;
114 #endif
115 }
116 #endif
117
118 /* detachstate appeared in Draft 6, but without manifest constants.
119  * in Draft 7 they were called PTHREAD_CREATE_UNDETACHED and ...DETACHED.
120  * in Draft 8 on, ...UNDETACHED became ...JOINABLE.
121  */
122 #ifndef PTHREAD_CREATE_JOINABLE
123 #ifdef PTHREAD_CREATE_UNDETACHED
124 #define PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED
125 #else
126 #define PTHREAD_CREATE_JOINABLE 0
127 #endif
128 #endif
129
130 #ifndef PTHREAD_CREATE_DETACHED
131 #define PTHREAD_CREATE_DETACHED 1
132 #endif
133
134 int 
135 ldap_pvt_thread_create( ldap_pvt_thread_t * thread,
136         int detach,
137         void *(*start_routine)( void * ),
138         void *arg)
139 {
140         int rtn;
141         pthread_attr_t attr;
142
143 /* Always create the thread attrs, so we can set stacksize if we need to */
144 #if HAVE_PTHREADS > 5
145         pthread_attr_init(&attr);
146 #else
147         pthread_attr_create(&attr);
148 #endif
149
150 #ifdef LDAP_PVT_THREAD_SET_STACK_SIZE
151         /* this should be tunable */
152         pthread_attr_setstacksize( &attr, LDAP_PVT_THREAD_STACK_SIZE );
153         if ( ldap_int_stackguard )
154                 pthread_attr_setguardsize( &attr, LDAP_PVT_THREAD_STACK_SIZE );
155 #endif
156
157 #if HAVE_PTHREADS > 5
158         detach = detach ? PTHREAD_CREATE_DETACHED : PTHREAD_CREATE_JOINABLE;
159 #if HAVE_PTHREADS == 6
160         pthread_attr_setdetachstate(&attr, &detach);
161 #else
162         pthread_attr_setdetachstate(&attr, detach);
163 #endif
164 #endif
165
166 #if HAVE_PTHREADS < 5
167         rtn = pthread_create( thread, attr, start_routine, arg );
168 #else
169         rtn = pthread_create( thread, &attr, start_routine, arg );
170 #endif
171
172 #if HAVE_PTHREADS > 5
173         pthread_attr_destroy(&attr);
174 #else
175         pthread_attr_delete(&attr);
176         if( detach ) {
177                 pthread_detach( thread );
178         }
179 #endif
180
181 #if HAVE_PTHREADS < 7
182         if ( rtn < 0 ) rtn = errno;
183 #endif
184         return rtn;
185 }
186
187 void 
188 ldap_pvt_thread_exit( void *retval )
189 {
190         pthread_exit( retval );
191 }
192
193 int 
194 ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return )
195 {
196 #if HAVE_PTHREADS < 7
197         void *dummy;
198         if (thread_return==NULL)
199           thread_return=&dummy;
200 #endif
201         return ERRVAL( pthread_join( thread, thread_return ) );
202 }
203
204 int 
205 ldap_pvt_thread_kill( ldap_pvt_thread_t thread, int signo )
206 {
207 #if defined(HAVE_PTHREAD_KILL) && HAVE_PTHREADS > 4
208         /* MacOS 10.1 is detected as v10 but has no pthread_kill() */
209         return ERRVAL( pthread_kill( thread, signo ) );
210 #else
211         /* pthread package with DCE */
212         if (kill( getpid(), signo )<0)
213                 return errno;
214         return 0;
215 #endif
216 }
217
218 int 
219 ldap_pvt_thread_yield( void )
220 {
221 #ifdef REPLACE_BROKEN_YIELD
222 #ifdef HAVE_NANOSLEEP
223         struct timespec t = { 0, 0 };
224         nanosleep(&t, NULL);
225 #else
226         struct timeval tv = {0,0};
227         select( 0, NULL, NULL, NULL, &tv );
228 #endif
229         return 0;
230
231 #elif defined(HAVE_THR_YIELD)
232         thr_yield();
233         return 0;
234
235 #elif HAVE_PTHREADS == 10
236         return sched_yield();
237
238 #elif defined(_POSIX_THREAD_IS_GNU_PTH)
239         sched_yield();
240         return 0;
241
242 #elif HAVE_PTHREADS == 6
243         pthread_yield(NULL);
244         return 0;
245
246 #else
247         pthread_yield();
248         return 0;
249 #endif
250 }
251
252 int 
253 ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond )
254 {
255         return ERRVAL( pthread_cond_init(
256                 cond, LDAP_INT_THREAD_CONDATTR_DEFAULT ) );
257 }
258
259 int 
260 ldap_pvt_thread_cond_destroy( ldap_pvt_thread_cond_t *cond )
261 {
262         return ERRVAL( pthread_cond_destroy( cond ) );
263 }
264         
265 int 
266 ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond )
267 {
268         return ERRVAL( pthread_cond_signal( cond ) );
269 }
270
271 int
272 ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cond )
273 {
274         return ERRVAL( pthread_cond_broadcast( cond ) );
275 }
276
277 int 
278 ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond, 
279                       ldap_pvt_thread_mutex_t *mutex )
280 {
281         return ERRVAL( pthread_cond_wait( cond, mutex ) );
282 }
283
284 int 
285 ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex )
286 {
287         return ERRVAL( pthread_mutex_init(
288                 mutex, LDAP_INT_THREAD_MUTEXATTR_DEFAULT ) );
289 }
290
291 int 
292 ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex )
293 {
294         return ERRVAL( pthread_mutex_destroy( mutex ) );
295 }
296
297 int 
298 ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex )
299 {
300         return ERRVAL( pthread_mutex_lock( mutex ) );
301 }
302
303 int 
304 ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mutex )
305 {
306         return ERRVAL( pthread_mutex_trylock( mutex ) );
307 }
308
309 int 
310 ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex )
311 {
312         return ERRVAL( pthread_mutex_unlock( mutex ) );
313 }
314
315 ldap_pvt_thread_t ldap_pvt_thread_self( void )
316 {
317         return pthread_self();
318 }
319
320 int
321 ldap_pvt_thread_key_create( ldap_pvt_thread_key_t *key )
322 {
323         return pthread_key_create( key, NULL );
324 }
325
326 int
327 ldap_pvt_thread_key_destroy( ldap_pvt_thread_key_t key )
328 {
329         return pthread_key_delete( key );
330 }
331
332 int
333 ldap_pvt_thread_key_setdata( ldap_pvt_thread_key_t key, void *data )
334 {
335         return pthread_setspecific( key, data );
336 }
337
338 int
339 ldap_pvt_thread_key_getdata( ldap_pvt_thread_key_t key, void **data )
340 {
341         *data = pthread_getspecific( key );
342         return 0;
343 }
344
345 #ifdef LDAP_THREAD_HAVE_RDWR
346 #ifdef HAVE_PTHREAD_RWLOCK_DESTROY
347 int 
348 ldap_pvt_thread_rdwr_init( ldap_pvt_thread_rdwr_t *rw )
349 {
350         return ERRVAL( pthread_rwlock_init( rw, NULL ) );
351 }
352
353 int 
354 ldap_pvt_thread_rdwr_destroy( ldap_pvt_thread_rdwr_t *rw )
355 {
356         return ERRVAL( pthread_rwlock_destroy( rw ) );
357 }
358
359 int ldap_pvt_thread_rdwr_rlock( ldap_pvt_thread_rdwr_t *rw )
360 {
361         return ERRVAL( pthread_rwlock_rdlock( rw ) );
362 }
363
364 int ldap_pvt_thread_rdwr_rtrylock( ldap_pvt_thread_rdwr_t *rw )
365 {
366         return ERRVAL( pthread_rwlock_tryrdlock( rw ) );
367 }
368
369 int ldap_pvt_thread_rdwr_runlock( ldap_pvt_thread_rdwr_t *rw )
370 {
371         return ERRVAL( pthread_rwlock_unlock( rw ) );
372 }
373
374 int ldap_pvt_thread_rdwr_wlock( ldap_pvt_thread_rdwr_t *rw )
375 {
376         return ERRVAL( pthread_rwlock_wrlock( rw ) );
377 }
378
379 int ldap_pvt_thread_rdwr_wtrylock( ldap_pvt_thread_rdwr_t *rw )
380 {
381         return ERRVAL( pthread_rwlock_trywrlock( rw ) );
382 }
383
384 int ldap_pvt_thread_rdwr_wunlock( ldap_pvt_thread_rdwr_t *rw )
385 {
386         return ERRVAL( pthread_rwlock_unlock( rw ) );
387 }
388
389 #endif /* HAVE_PTHREAD_RWLOCK_DESTROY */
390 #endif /* LDAP_THREAD_HAVE_RDWR */
391 #endif /* HAVE_PTHREADS */
392