1/* $NetBSD: thr_nt.c,v 1.1.1.3 2010/12/12 15:21:43 adam Exp $ */ 2 3/* thr_nt.c - wrapper around NT threads */ 4/* OpenLDAP: pkg/ldap/libraries/libldap_r/thr_nt.c,v 1.32.2.7 2010/04/13 20:23:03 kurt Exp */ 5/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 6 * 7 * Copyright 1998-2010 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 "portable.h" 20 21#if defined( HAVE_NT_THREADS ) 22 23#define _WIN32_WINNT 0x0400 24#include <windows.h> 25#include <process.h> 26 27#include "ldap_pvt_thread.h" /* Get the thread interface */ 28#define LDAP_THREAD_IMPLEMENTATION 29#include "ldap_thr_debug.h" /* May rename the symbols defined below */ 30 31typedef struct ldap_int_thread_s { 32 long tid; 33 HANDLE thd; 34} ldap_int_thread_s; 35 36#ifndef NT_MAX_THREADS 37#define NT_MAX_THREADS 1024 38#endif 39 40static ldap_int_thread_s tids[NT_MAX_THREADS]; 41static int ntids; 42 43 44/* mingw compiler very sensitive about getting prototypes right */ 45typedef unsigned __stdcall thrfunc_t(void *); 46 47int 48ldap_int_thread_initialize( void ) 49{ 50 return 0; 51} 52 53int 54ldap_int_thread_destroy( void ) 55{ 56 return 0; 57} 58 59int 60ldap_pvt_thread_create( ldap_pvt_thread_t * thread, 61 int detach, 62 void *(*start_routine)( void *), 63 void *arg) 64{ 65 unsigned tid; 66 HANDLE thd; 67 int rc = -1; 68 69 thd = (HANDLE) _beginthreadex(NULL, LDAP_PVT_THREAD_STACK_SIZE, (thrfunc_t *) start_routine, 70 arg, 0, &tid); 71 72 if ( thd ) { 73 *thread = (ldap_pvt_thread_t) tid; 74 tids[ntids].tid = tid; 75 tids[ntids].thd = thd; 76 ntids++; 77 rc = 0; 78 } 79 return rc; 80} 81 82void 83ldap_pvt_thread_exit( void *retval ) 84{ 85 _endthread( ); 86} 87 88int 89ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return ) 90{ 91 DWORD status; 92 int i; 93 94 for (i=0; i<ntids; i++) { 95 if ( tids[i].tid == thread ) 96 break; 97 } 98 if ( i > ntids ) return -1; 99 100 status = WaitForSingleObject( tids[i].thd, INFINITE ); 101 for (; i<ntids; i++) { 102 tids[i] = tids[i+1]; 103 } 104 ntids--; 105 return status == WAIT_FAILED ? -1 : 0; 106} 107 108int 109ldap_pvt_thread_kill( ldap_pvt_thread_t thread, int signo ) 110{ 111 return 0; 112} 113 114int 115ldap_pvt_thread_yield( void ) 116{ 117 Sleep( 0 ); 118 return 0; 119} 120 121int 122ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond ) 123{ 124 *cond = CreateEvent( NULL, FALSE, FALSE, NULL ); 125 return( 0 ); 126} 127 128int 129ldap_pvt_thread_cond_destroy( ldap_pvt_thread_cond_t *cv ) 130{ 131 CloseHandle( *cv ); 132 return( 0 ); 133} 134 135int 136ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond ) 137{ 138 SetEvent( *cond ); 139 return( 0 ); 140} 141 142int 143ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond, 144 ldap_pvt_thread_mutex_t *mutex ) 145{ 146 SignalObjectAndWait( *mutex, *cond, INFINITE, FALSE ); 147 WaitForSingleObject( *mutex, INFINITE ); 148 return( 0 ); 149} 150 151int 152ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cond ) 153{ 154 while ( WaitForSingleObject( *cond, 0 ) == WAIT_TIMEOUT ) 155 SetEvent( *cond ); 156 return( 0 ); 157} 158 159int 160ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex ) 161{ 162 *mutex = CreateMutex( NULL, 0, NULL ); 163 return ( 0 ); 164} 165 166int 167ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex ) 168{ 169 CloseHandle( *mutex ); 170 return ( 0 ); 171} 172 173int 174ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex ) 175{ 176 DWORD status; 177 status = WaitForSingleObject( *mutex, INFINITE ); 178 return status == WAIT_FAILED ? -1 : 0; 179} 180 181int 182ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex ) 183{ 184 ReleaseMutex( *mutex ); 185 return ( 0 ); 186} 187 188int 189ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mp ) 190{ 191 DWORD status; 192 status = WaitForSingleObject( *mp, 0 ); 193 return status == WAIT_FAILED || status == WAIT_TIMEOUT 194 ? -1 : 0; 195} 196 197ldap_pvt_thread_t 198ldap_pvt_thread_self( void ) 199{ 200 return GetCurrentThreadId(); 201} 202 203int 204ldap_pvt_thread_key_create( ldap_pvt_thread_key_t *keyp ) 205{ 206 DWORD key = TlsAlloc(); 207 if ( key != TLS_OUT_OF_INDEXES ) { 208 *keyp = key; 209 return 0; 210 } else { 211 return -1; 212 } 213} 214 215int 216ldap_pvt_thread_key_destroy( ldap_pvt_thread_key_t key ) 217{ 218 /* TlsFree returns 0 on failure */ 219 return( TlsFree( key ) == 0 ); 220} 221 222int 223ldap_pvt_thread_key_setdata( ldap_pvt_thread_key_t key, void *data ) 224{ 225 return ( TlsSetValue( key, data ) == 0 ); 226} 227 228int 229ldap_pvt_thread_key_getdata( ldap_pvt_thread_key_t key, void **data ) 230{ 231 void *ptr = TlsGetValue( key ); 232 *data = ptr; 233 return( ptr ? GetLastError() : 0 ); 234} 235 236#endif 237