xref: /netbsd-src/external/bsd/openldap/dist/libraries/libldap/thr_pth.c (revision 549b59ed3ccf0d36d3097190a0db27b770f3a839)
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