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-2011 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 34static pth_attr_t detach_attr; 35static pth_attr_t joined_attr; 36 37int 38ldap_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 52int 53ldap_int_thread_destroy( void ) 54{ 55 pth_attr_destroy(detach_attr); 56 pth_kill(); 57 return 0; 58} 59 60int 61ldap_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 72void 73ldap_pvt_thread_exit( void *retval ) 74{ 75 pth_exit( retval ); 76} 77 78int ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return ) 79{ 80 return pth_join( thread, thread_return ) ? 0 : errno; 81} 82 83int 84ldap_pvt_thread_kill( ldap_pvt_thread_t thread, int signo ) 85{ 86 return pth_raise( thread, signo ) ? 0 : errno; 87} 88 89int 90ldap_pvt_thread_yield( void ) 91{ 92 return pth_yield(NULL) ? 0 : errno; 93} 94 95int 96ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond ) 97{ 98 return( pth_cond_init( cond ) ? 0 : errno ); 99} 100 101int 102ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond ) 103{ 104 return( pth_cond_notify( cond, 0 ) ? 0 : errno ); 105} 106 107int 108ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cond ) 109{ 110 return( pth_cond_notify( cond, 1 ) ? 0 : errno ); 111} 112 113int 114ldap_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 120int 121ldap_pvt_thread_cond_destroy( ldap_pvt_thread_cond_t *cv ) 122{ 123 return 0; 124} 125 126int 127ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex ) 128{ 129 return( pth_mutex_init( mutex ) ? 0 : errno ); 130} 131 132int 133ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex ) 134{ 135 return 0; 136} 137 138int 139ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex ) 140{ 141 return( pth_mutex_acquire( mutex, 0, NULL ) ? 0 : errno ); 142} 143 144int 145ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex ) 146{ 147 return( pth_mutex_release( mutex ) ? 0 : errno ); 148} 149 150int 151ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mutex ) 152{ 153 return( pth_mutex_acquire( mutex, 1, NULL ) ? 0 : errno ); 154} 155 156ldap_pvt_thread_t 157ldap_pvt_thread_self( void ) 158{ 159 return pth_self(); 160} 161 162int 163ldap_pvt_thread_key_create( ldap_pvt_thread_key_t *key ) 164{ 165 return pth_key_create( key, NULL ); 166} 167 168int 169ldap_pvt_thread_key_destroy( ldap_pvt_thread_key_t key ) 170{ 171 return pth_key_delete( key ); 172} 173 174int 175ldap_pvt_thread_key_setdata( ldap_pvt_thread_key_t key, void *data ) 176{ 177 return pth_key_setdata( key, data ); 178} 179 180int 181ldap_pvt_thread_key_getdata( ldap_pvt_thread_key_t key, void **data ) 182{ 183 *data = pth_key_getdata( key ); 184 return 0; 185} 186 187#ifdef LDAP_THREAD_HAVE_RDWR 188int 189ldap_pvt_thread_rdwr_init( ldap_pvt_thread_rdwr_t *rw ) 190{ 191 return pth_rwlock_init( rw ) ? 0 : errno; 192} 193 194int 195ldap_pvt_thread_rdwr_destroy( ldap_pvt_thread_rdwr_t *rw ) 196{ 197 return 0; 198} 199 200int ldap_pvt_thread_rdwr_rlock( ldap_pvt_thread_rdwr_t *rw ) 201{ 202 return pth_rwlock_acquire( rw, PTH_RWLOCK_RD, 0, NULL ) ? 0 : errno; 203} 204 205int ldap_pvt_thread_rdwr_rtrylock( ldap_pvt_thread_rdwr_t *rw ) 206{ 207 return pth_rwlock_acquire( rw, PTH_RWLOCK_RD, 1, NULL ) ? 0 : errno; 208} 209 210int ldap_pvt_thread_rdwr_runlock( ldap_pvt_thread_rdwr_t *rw ) 211{ 212 return pth_rwlock_release( rw ) ? 0 : errno; 213} 214 215int ldap_pvt_thread_rdwr_wlock( ldap_pvt_thread_rdwr_t *rw ) 216{ 217 return pth_rwlock_acquire( rw, PTH_RWLOCK_RW, 0, NULL ) ? 0 : errno; 218} 219 220int ldap_pvt_thread_rdwr_wtrylock( ldap_pvt_thread_rdwr_t *rw ) 221{ 222 return pth_rwlock_acquire( rw, PTH_RWLOCK_RW, 1, NULL ) ? 0 : errno; 223} 224 225int ldap_pvt_thread_rdwr_wunlock( ldap_pvt_thread_rdwr_t *rw ) 226{ 227 return pth_rwlock_release( rw ) ? 0 : errno; 228} 229 230#endif /* LDAP_THREAD_HAVE_RDWR */ 231#endif /* HAVE_GNU_PTH */ 232