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 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 58 ldap_int_thread_destroy( void ) 59 { 60 pth_attr_destroy(detach_attr); 61 pth_kill(); 62 return 0; 63 } 64 65 int 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 78 ldap_pvt_thread_exit( void *retval ) 79 { 80 pth_exit( retval ); 81 } 82 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 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 95 ldap_pvt_thread_yield( void ) 96 { 97 return pth_yield(NULL) ? 0 : errno; 98 } 99 100 int 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 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 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 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 126 ldap_pvt_thread_cond_destroy( ldap_pvt_thread_cond_t *cv ) 127 { 128 return 0; 129 } 130 131 int 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 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 145 ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex ) 146 { 147 return 0; 148 } 149 150 int 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 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 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 169 ldap_pvt_thread_self( void ) 170 { 171 return pth_self(); 172 } 173 174 int 175 ldap_pvt_thread_key_create( ldap_pvt_thread_key_t *key ) 176 { 177 return pth_key_create( key, NULL ); 178 } 179 180 int 181 ldap_pvt_thread_key_destroy( ldap_pvt_thread_key_t key ) 182 { 183 return pth_key_delete( key ); 184 } 185 186 int 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 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 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 207 ldap_pvt_thread_rdwr_destroy( ldap_pvt_thread_rdwr_t *rw ) 208 { 209 return 0; 210 } 211 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 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 222 int ldap_pvt_thread_rdwr_runlock( ldap_pvt_thread_rdwr_t *rw ) 223 { 224 return pth_rwlock_release( rw ) ? 0 : errno; 225 } 226 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 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 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