]> git.sur5r.net Git - openldap/blob - libraries/libldap_r/thr_pth.c
ITS#8638 Add a recursive mutex to libldap_r for libevent
[openldap] / libraries / libldap_r / thr_pth.c
1 /* thr_pth.c - wrappers around GNU Pth */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 1998-2017 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_GNU_PTH )
20
21 #include "ldap_pvt_thread.h" /* Get the thread interface */
22 #define LDAP_THREAD_IMPLEMENTATION
23 #define LDAP_THREAD_RDWR_IMPLEMENTATION
24 #include "ldap_thr_debug.h"      /* May rename the symbols defined below */
25
26 #include <errno.h>
27
28 /*******************
29  *                 *
30  * GNU Pth Threads *
31  *                 *
32  *******************/
33
34 static pth_attr_t detach_attr;
35 static pth_attr_t joined_attr;
36
37 int
38 ldap_int_thread_initialize( void )
39 {
40         if( !pth_init() ) {
41                 return -1;
42         }
43         detach_attr = pth_attr_new();
44         joined_attr = pth_attr_new();
45 #ifdef LDAP_PVT_THREAD_SET_STACK_SIZE
46         pth_attr_set( joined_attr, PTH_ATTR_STACK_SIZE, LDAP_PVT_THREAD_STACK_SIZE );
47         pth_attr_set( detach_attr, PTH_ATTR_STACK_SIZE, LDAP_PVT_THREAD_STACK_SIZE );
48 #endif
49         return pth_attr_set( detach_attr, PTH_ATTR_JOINABLE, FALSE );
50 }
51
52 int
53 ldap_int_thread_destroy( void )
54 {
55         pth_attr_destroy(detach_attr);
56         pth_kill();
57         return 0;
58 }
59
60 int 
61 ldap_pvt_thread_create( ldap_pvt_thread_t * thread, 
62         int detach,
63         void *(*start_routine)( void *),
64         void *arg)
65 {
66         *thread = pth_spawn( detach ? detach_attr : joined_attr,
67                 start_routine, arg );
68
69         return *thread == NULL ? errno : 0;
70 }
71
72 void 
73 ldap_pvt_thread_exit( void *retval )
74 {
75         pth_exit( retval );
76 }
77
78 int ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return )
79 {
80         return pth_join( thread, thread_return ) ? 0 : errno;
81 }
82
83 int 
84 ldap_pvt_thread_kill( ldap_pvt_thread_t thread, int signo )
85 {
86         return pth_raise( thread, signo ) ? 0 : errno;
87 }
88         
89 int 
90 ldap_pvt_thread_yield( void )
91 {
92         return pth_yield(NULL) ? 0 : errno;
93 }
94
95 int 
96 ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond )
97 {
98         return( pth_cond_init( cond ) ? 0 : errno );
99 }
100
101 int 
102 ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond )
103 {
104         return( pth_cond_notify( cond, 0 ) ? 0 : errno );
105 }
106
107 int
108 ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cond )
109 {
110         return( pth_cond_notify( cond, 1 ) ? 0 : errno );
111 }
112
113 int 
114 ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond, 
115         ldap_pvt_thread_mutex_t *mutex )
116 {
117         return( pth_cond_await( cond, mutex, NULL ) ? 0 : errno );
118 }
119
120 int
121 ldap_pvt_thread_cond_destroy( ldap_pvt_thread_cond_t *cv )
122 {
123         return 0;
124 }
125
126 int 
127 ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex )
128 {
129         return( pth_mutex_init( mutex ) ? 0 : errno );
130 }
131
132 int
133 ldap_pvt_thread_mutex_recursive_init( ldap_pvt_thread_mutex_t *mutex )
134 {
135         /* All pth mutexes are recursive */
136         return ldap_pvt_thread_mutex_init( mutex );
137 }
138
139 int 
140 ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex )
141 {
142         return 0;
143 }
144
145 int 
146 ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex )
147 {
148         return( pth_mutex_acquire( mutex, 0, NULL ) ? 0 : errno );
149 }
150
151 int 
152 ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex )
153 {
154         return( pth_mutex_release( mutex ) ? 0 : errno );
155 }
156
157 int
158 ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mutex )
159 {
160         return( pth_mutex_acquire( mutex, 1, NULL ) ? 0 : errno );
161 }
162
163 int ldap_pvt_thread_mutex_recursive_init( ldap_pvt_thread_mutex_recursive_t *mutex )
164         LDAP_GCCATTR((alias("ldap_pvt_thread_mutex_init")));
165 int ldap_pvt_thread_mutex_recursive_destroy( ldap_pvt_thread_mutex_recursive_t *mutex )
166         LDAP_GCCATTR((alias("ldap_pvt_thread_mutex_destroy")));
167 int ldap_pvt_thread_mutex_recursive_lock( ldap_pvt_thread_mutex_recursive_t *mutex )
168         LDAP_GCCATTR((alias("ldap_pvt_thread_mutex_lock")));
169 int ldap_pvt_thread_mutex_recursive_trylock( ldap_pvt_thread_mutex_recursive_t *mutex )
170         LDAP_GCCATTR((alias("ldap_pvt_thread_mutex_trylock")));
171 int ldap_pvt_thread_mutex_recursive_unlock( ldap_pvt_thread_mutex_recursive_t *mutex )
172         LDAP_GCCATTR((alias("ldap_pvt_thread_mutex_unlock")));
173
174 ldap_pvt_thread_t
175 ldap_pvt_thread_self( void )
176 {
177         return pth_self();
178 }
179
180 int
181 ldap_pvt_thread_key_create( ldap_pvt_thread_key_t *key )
182 {
183         return pth_key_create( key, NULL );
184 }
185
186 int
187 ldap_pvt_thread_key_destroy( ldap_pvt_thread_key_t key )
188 {
189         return pth_key_delete( key );
190 }
191
192 int
193 ldap_pvt_thread_key_setdata( ldap_pvt_thread_key_t key, void *data )
194 {
195         return pth_key_setdata( key, data );
196 }
197
198 int
199 ldap_pvt_thread_key_getdata( ldap_pvt_thread_key_t key, void **data )
200 {
201         *data = pth_key_getdata( key );
202         return 0;
203 }
204
205 #ifdef LDAP_THREAD_HAVE_RDWR
206 int 
207 ldap_pvt_thread_rdwr_init( ldap_pvt_thread_rdwr_t *rw )
208 {
209         return pth_rwlock_init( rw ) ? 0 : errno;
210 }
211
212 int 
213 ldap_pvt_thread_rdwr_destroy( ldap_pvt_thread_rdwr_t *rw )
214 {
215         return 0;
216 }
217
218 int ldap_pvt_thread_rdwr_rlock( ldap_pvt_thread_rdwr_t *rw )
219 {
220         return pth_rwlock_acquire( rw, PTH_RWLOCK_RD, 0, NULL ) ? 0 : errno;
221 }
222
223 int ldap_pvt_thread_rdwr_rtrylock( ldap_pvt_thread_rdwr_t *rw )
224 {
225         return pth_rwlock_acquire( rw, PTH_RWLOCK_RD, 1, NULL ) ? 0 : errno;
226 }
227
228 int ldap_pvt_thread_rdwr_runlock( ldap_pvt_thread_rdwr_t *rw )
229 {
230         return pth_rwlock_release( rw ) ? 0 : errno;
231 }
232
233 int ldap_pvt_thread_rdwr_wlock( ldap_pvt_thread_rdwr_t *rw )
234 {
235         return pth_rwlock_acquire( rw, PTH_RWLOCK_RW, 0, NULL ) ? 0 : errno;
236 }
237
238 int ldap_pvt_thread_rdwr_wtrylock( ldap_pvt_thread_rdwr_t *rw )
239 {
240         return pth_rwlock_acquire( rw, PTH_RWLOCK_RW, 1, NULL ) ? 0 : errno;
241 }
242
243 int ldap_pvt_thread_rdwr_wunlock( ldap_pvt_thread_rdwr_t *rw )
244 {
245         return pth_rwlock_release( rw ) ? 0 : errno;
246 }
247
248 #endif /* LDAP_THREAD_HAVE_RDWR */
249 #endif /* HAVE_GNU_PTH */