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