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