Back to index

openldap  2.4.31
thr_nt.c
Go to the documentation of this file.
00001 /* thr_nt.c - wrapper around NT threads */
00002 /* $OpenLDAP$ */
00003 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00004  *
00005  * Copyright 1998-2012 The OpenLDAP Foundation.
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted only as authorized by the OpenLDAP
00010  * Public License.
00011  *
00012  * A copy of this license is available in file LICENSE in the
00013  * top-level directory of the distribution or, alternatively, at
00014  * <http://www.OpenLDAP.org/license.html>.
00015  */
00016 
00017 #include "portable.h"
00018 
00019 #if defined( HAVE_NT_THREADS )
00020 
00021 #define _WIN32_WINNT 0x0400
00022 #include <windows.h>
00023 #include <process.h>
00024 
00025 #include "ldap_pvt_thread.h" /* Get the thread interface */
00026 #define LDAP_THREAD_IMPLEMENTATION
00027 #include "ldap_thr_debug.h"  /* May rename the symbols defined below */
00028 
00029 typedef struct ldap_int_thread_s {
00030        long tid;
00031        HANDLE thd;
00032 } ldap_int_thread_s;
00033 
00034 #ifndef NT_MAX_THREADS
00035 #define NT_MAX_THREADS      1024
00036 #endif
00037 
00038 static ldap_int_thread_s tids[NT_MAX_THREADS];
00039 static int ntids;
00040 
00041 
00042 /* mingw compiler very sensitive about getting prototypes right */
00043 typedef unsigned __stdcall thrfunc_t(void *);
00044 
00045 int
00046 ldap_int_thread_initialize( void )
00047 {
00048        return 0;
00049 }
00050 
00051 int
00052 ldap_int_thread_destroy( void )
00053 {
00054        return 0;
00055 }
00056 
00057 int 
00058 ldap_pvt_thread_create( ldap_pvt_thread_t * thread, 
00059        int detach,
00060        void *(*start_routine)( void *),
00061        void *arg)
00062 {
00063        unsigned tid;
00064        HANDLE thd;
00065        int rc = -1;
00066 
00067        thd = (HANDLE) _beginthreadex(NULL, LDAP_PVT_THREAD_STACK_SIZE, (thrfunc_t *) start_routine,
00068                                   arg, 0, &tid);
00069 
00070        if ( thd ) {
00071               *thread = (ldap_pvt_thread_t) tid;
00072               tids[ntids].tid = tid;
00073               tids[ntids].thd = thd;
00074               ntids++;
00075               rc = 0;
00076        }
00077        return rc;
00078 }
00079        
00080 void 
00081 ldap_pvt_thread_exit( void *retval )
00082 {
00083        _endthread( );
00084 }
00085 
00086 int 
00087 ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return )
00088 {
00089        DWORD status;
00090        int i;
00091 
00092        for (i=0; i<ntids; i++) {
00093               if ( tids[i].tid == thread )
00094                      break;
00095        }
00096        if ( i > ntids ) return -1;
00097 
00098        status = WaitForSingleObject( tids[i].thd, INFINITE );
00099        for (; i<ntids; i++) {
00100               tids[i] = tids[i+1];
00101        }
00102        ntids--;
00103        return status == WAIT_FAILED ? -1 : 0;
00104 }
00105 
00106 int 
00107 ldap_pvt_thread_kill( ldap_pvt_thread_t thread, int signo )
00108 {
00109        return 0;
00110 }
00111 
00112 int 
00113 ldap_pvt_thread_yield( void )
00114 {
00115        Sleep( 0 );
00116        return 0;
00117 }
00118 
00119 int 
00120 ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond )
00121 {
00122        *cond = CreateEvent( NULL, FALSE, FALSE, NULL );
00123        return( 0 );
00124 }
00125 
00126 int
00127 ldap_pvt_thread_cond_destroy( ldap_pvt_thread_cond_t *cv )
00128 {
00129        CloseHandle( *cv );
00130        return( 0 );
00131 }
00132 
00133 int 
00134 ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond )
00135 {
00136        SetEvent( *cond );
00137        return( 0 );
00138 }
00139 
00140 int 
00141 ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond, 
00142        ldap_pvt_thread_mutex_t *mutex )
00143 {
00144        SignalObjectAndWait( *mutex, *cond, INFINITE, FALSE );
00145        WaitForSingleObject( *mutex, INFINITE );
00146        return( 0 );
00147 }
00148 
00149 int
00150 ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cond )
00151 {
00152        while ( WaitForSingleObject( *cond, 0 ) == WAIT_TIMEOUT )
00153               SetEvent( *cond );
00154        return( 0 );
00155 }
00156 
00157 int 
00158 ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex )
00159 {
00160        *mutex = CreateMutex( NULL, 0, NULL );
00161        return ( 0 );
00162 }
00163 
00164 int 
00165 ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex )
00166 {
00167        CloseHandle( *mutex );
00168        return ( 0 ); 
00169 }
00170 
00171 int 
00172 ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex )
00173 {
00174        DWORD status;
00175        status = WaitForSingleObject( *mutex, INFINITE );
00176        return status == WAIT_FAILED ? -1 : 0;
00177 }
00178 
00179 int 
00180 ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex )
00181 {
00182        ReleaseMutex( *mutex );
00183        return ( 0 );
00184 }
00185 
00186 int
00187 ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mp )
00188 {
00189        DWORD status;
00190        status = WaitForSingleObject( *mp, 0 );
00191        return status == WAIT_FAILED || status == WAIT_TIMEOUT
00192               ? -1 : 0;
00193 }
00194 
00195 ldap_pvt_thread_t
00196 ldap_pvt_thread_self( void )
00197 {
00198        return GetCurrentThreadId();
00199 }
00200 
00201 int
00202 ldap_pvt_thread_key_create( ldap_pvt_thread_key_t *keyp )
00203 {
00204        DWORD key = TlsAlloc();
00205        if ( key != TLS_OUT_OF_INDEXES ) {
00206               *keyp = key;
00207               return 0;
00208        } else {
00209               return -1;
00210        }
00211 }
00212 
00213 int
00214 ldap_pvt_thread_key_destroy( ldap_pvt_thread_key_t key )
00215 {
00216        /* TlsFree returns 0 on failure */
00217        return( TlsFree( key ) == 0 );
00218 }
00219 
00220 int
00221 ldap_pvt_thread_key_setdata( ldap_pvt_thread_key_t key, void *data )
00222 {
00223        return ( TlsSetValue( key, data ) == 0 );
00224 }
00225 
00226 int
00227 ldap_pvt_thread_key_getdata( ldap_pvt_thread_key_t key, void **data )
00228 {
00229        void *ptr = TlsGetValue( key );
00230        *data = ptr;
00231        return( ptr ? GetLastError() : 0 );
00232 }
00233 
00234 #endif