1 /* thr_nt.c - wrapper around NT threads */
2 /* $OpenLDAP: pkg/ldap/libraries/libldap_r/thr_nt.c,v 1.32.2.5 2008/02/11 23:26:42 kurt Exp $ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 1998-2008 The OpenLDAP Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
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>.
19 #if defined( HAVE_NT_THREADS )
21 #define _WIN32_WINNT 0x0400
25 #include "ldap_pvt_thread.h" /* Get the thread interface */
26 #define LDAP_THREAD_IMPLEMENTATION
27 #include "ldap_thr_debug.h" /* May rename the symbols defined below */
29 typedef struct ldap_int_thread_s
{
34 #ifndef NT_MAX_THREADS
35 #define NT_MAX_THREADS 1024
38 static ldap_int_thread_s tids
[NT_MAX_THREADS
];
42 /* mingw compiler very sensitive about getting prototypes right */
43 typedef unsigned __stdcall
thrfunc_t(void *);
46 ldap_int_thread_initialize( void )
52 ldap_int_thread_destroy( void )
58 ldap_pvt_thread_create( ldap_pvt_thread_t
* thread
,
60 void *(*start_routine
)( void *),
67 thd
= (HANDLE
) _beginthreadex(NULL
, LDAP_PVT_THREAD_STACK_SIZE
, (thrfunc_t
*) start_routine
,
71 *thread
= (ldap_pvt_thread_t
) tid
;
72 tids
[ntids
].tid
= tid
;
73 tids
[ntids
].thd
= thd
;
81 ldap_pvt_thread_exit( void *retval
)
87 ldap_pvt_thread_join( ldap_pvt_thread_t thread
, void **thread_return
)
92 for (i
=0; i
<ntids
; i
++) {
93 if ( tids
[i
].tid
== thread
)
96 if ( i
> ntids
) return -1;
98 status
= WaitForSingleObject( tids
[i
].thd
, INFINITE
);
99 for (; i
<ntids
; i
++) {
103 return status
== WAIT_FAILED
? -1 : 0;
107 ldap_pvt_thread_kill( ldap_pvt_thread_t thread
, int signo
)
113 ldap_pvt_thread_yield( void )
120 ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t
*cond
)
122 *cond
= CreateEvent( NULL
, FALSE
, FALSE
, NULL
);
127 ldap_pvt_thread_cond_destroy( ldap_pvt_thread_cond_t
*cv
)
134 ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t
*cond
)
141 ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t
*cond
,
142 ldap_pvt_thread_mutex_t
*mutex
)
144 SignalObjectAndWait( *mutex
, *cond
, INFINITE
, FALSE
);
145 WaitForSingleObject( *mutex
, INFINITE
);
150 ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t
*cond
)
152 while ( WaitForSingleObject( *cond
, 0 ) == WAIT_TIMEOUT
)
158 ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t
*mutex
)
160 *mutex
= CreateMutex( NULL
, 0, NULL
);
165 ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t
*mutex
)
167 CloseHandle( *mutex
);
172 ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t
*mutex
)
175 status
= WaitForSingleObject( *mutex
, INFINITE
);
176 return status
== WAIT_FAILED
? -1 : 0;
180 ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t
*mutex
)
182 ReleaseMutex( *mutex
);
187 ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t
*mp
)
190 status
= WaitForSingleObject( *mp
, 0 );
191 return status
== WAIT_FAILED
|| status
== WAIT_TIMEOUT
196 ldap_pvt_thread_self( void )
198 return GetCurrentThreadId();
202 ldap_pvt_thread_key_create( ldap_pvt_thread_key_t
*keyp
)
204 DWORD key
= TlsAlloc();
205 if ( key
!= TLS_OUT_OF_INDEXES
) {
214 ldap_pvt_thread_key_destroy( ldap_pvt_thread_key_t key
)
216 /* TlsFree returns 0 on failure */
217 return( TlsFree( key
) == 0 );
221 ldap_pvt_thread_key_setdata( ldap_pvt_thread_key_t key
, void *data
)
223 return ( TlsSetValue( key
, data
) == 0 );
227 ldap_pvt_thread_key_getdata( ldap_pvt_thread_key_t key
, void **data
)
229 void *ptr
= TlsGetValue( key
);
231 return( ptr
? GetLastError() : 0 );