]>
git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/thread/arch/thread_win.c
2 * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
10 #include <internal/thread_arch.h>
12 #if defined(OPENSSL_THREADS_WINNT)
16 static DWORD __stdcall
thread_start_thunk(LPVOID vthread
)
18 CRYPTO_THREAD
*thread
;
19 CRYPTO_THREAD_RETVAL ret
;
21 thread
= (CRYPTO_THREAD
*)vthread
;
23 thread
->thread_id
= GetCurrentThreadId();
25 ret
= thread
->routine(thread
->data
);
26 ossl_crypto_mutex_lock(thread
->statelock
);
27 CRYPTO_THREAD_SET_STATE(thread
, CRYPTO_THREAD_FINISHED
);
29 ossl_crypto_condvar_signal(thread
->condvar
);
30 ossl_crypto_mutex_unlock(thread
->statelock
);
35 int ossl_crypto_thread_native_spawn(CRYPTO_THREAD
*thread
)
39 handle
= OPENSSL_zalloc(sizeof(*handle
));
43 *handle
= (HANDLE
)_beginthreadex(NULL
, 0, &thread_start_thunk
, thread
, 0, NULL
);
47 thread
->handle
= handle
;
51 thread
->handle
= NULL
;
56 int ossl_crypto_thread_native_perform_join(CRYPTO_THREAD
*thread
, CRYPTO_THREAD_RETVAL
*retval
)
61 if (thread
== NULL
|| thread
->handle
== NULL
)
64 handle
= (HANDLE
*) thread
->handle
;
65 if (WaitForSingleObject(*handle
, INFINITE
) != WAIT_OBJECT_0
)
68 if (GetExitCodeThread(*handle
, &thread_retval
) == 0)
72 * GetExitCodeThread call followed by this check is to make sure that
73 * the thread exitted properly. In particular, thread_retval may be
74 * non-zero when exitted via explicit ExitThread/TerminateThread or
75 * if the thread is still active (returns STILL_ACTIVE (259)).
77 if (thread_retval
!= 0)
80 if (CloseHandle(*handle
) == 0)
86 int ossl_crypto_thread_native_exit(void)
92 int ossl_crypto_thread_native_is_self(CRYPTO_THREAD
*thread
)
94 return thread
->thread_id
== GetCurrentThreadId();
97 CRYPTO_MUTEX
*ossl_crypto_mutex_new(void)
99 CRITICAL_SECTION
*mutex
;
101 if ((mutex
= OPENSSL_zalloc(sizeof(*mutex
))) == NULL
)
103 InitializeCriticalSection(mutex
);
104 return (CRYPTO_MUTEX
*)mutex
;
107 void ossl_crypto_mutex_lock(CRYPTO_MUTEX
*mutex
)
109 CRITICAL_SECTION
*mutex_p
;
111 mutex_p
= (CRITICAL_SECTION
*)mutex
;
112 EnterCriticalSection(mutex_p
);
115 int ossl_crypto_mutex_try_lock(CRYPTO_MUTEX
*mutex
)
117 CRITICAL_SECTION
*mutex_p
;
119 mutex_p
= (CRITICAL_SECTION
*)mutex
;
120 if (TryEnterCriticalSection(mutex_p
))
126 void ossl_crypto_mutex_unlock(CRYPTO_MUTEX
*mutex
)
128 CRITICAL_SECTION
*mutex_p
;
130 mutex_p
= (CRITICAL_SECTION
*)mutex
;
131 LeaveCriticalSection(mutex_p
);
134 void ossl_crypto_mutex_free(CRYPTO_MUTEX
**mutex
)
136 CRITICAL_SECTION
**mutex_p
;
138 mutex_p
= (CRITICAL_SECTION
**)mutex
;
139 if (*mutex_p
!= NULL
)
140 DeleteCriticalSection(*mutex_p
);
141 OPENSSL_free(*mutex_p
);
145 static int determine_timeout(OSSL_TIME deadline
, DWORD
*w_timeout_p
)
147 OSSL_TIME now
, delta
;
150 if (ossl_time_is_infinite(deadline
)) {
151 *w_timeout_p
= INFINITE
;
155 now
= ossl_time_now();
156 delta
= ossl_time_subtract(deadline
, now
);
158 if (ossl_time_is_zero(delta
))
161 ms
= ossl_time2ms(delta
);
165 * Amount of time we want to wait is too long for the 32-bit argument to
166 * the Win32 API, so just wait as long as possible.
168 if (ms
> (uint64_t)(INFINITE
- 1))
169 *w_timeout_p
= INFINITE
- 1;
171 *w_timeout_p
= (DWORD
)ms
;
176 # if defined(OPENSSL_THREADS_WINNT_LEGACY)
178 CRYPTO_CONDVAR
*ossl_crypto_condvar_new(void)
182 if ((h
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
)) == NULL
)
185 return (CRYPTO_CONDVAR
*)h
;
188 void ossl_crypto_condvar_wait(CRYPTO_CONDVAR
*cv
, CRYPTO_MUTEX
*mutex
)
190 ossl_crypto_mutex_unlock(mutex
);
191 WaitForSingleObject((HANDLE
)cv
, INFINITE
);
192 ossl_crypto_mutex_lock(mutex
);
195 void ossl_crypto_condvar_wait_timeout(CRYPTO_CONDVAR
*cv
, CRYPTO_MUTEX
*mutex
,
200 fprintf(stderr
, "# wt\n"); fflush(stderr
);
201 if (!determine_timeout(deadline
, &timeout
))
204 ossl_crypto_mutex_unlock(mutex
);
205 WaitForSingleObject((HANDLE
)cv
, timeout
);
206 fprintf(stderr
, "# wtd\n"); fflush(stderr
);
207 ossl_crypto_mutex_lock(mutex
);
208 fprintf(stderr
, "# wtd2\n"); fflush(stderr
);
211 void ossl_crypto_condvar_broadcast(CRYPTO_CONDVAR
*cv
)
216 void ossl_crypto_condvar_signal(CRYPTO_CONDVAR
*cv
)
218 HANDLE
*cv_p
= (HANDLE
*)cv
;
223 void ossl_crypto_condvar_free(CRYPTO_CONDVAR
**cv
)
227 cv_p
= (HANDLE
**)cv
;
236 CRYPTO_CONDVAR
*ossl_crypto_condvar_new(void)
238 CONDITION_VARIABLE
*cv_p
;
240 if ((cv_p
= OPENSSL_zalloc(sizeof(*cv_p
))) == NULL
)
242 InitializeConditionVariable(cv_p
);
243 return (CRYPTO_CONDVAR
*)cv_p
;
246 void ossl_crypto_condvar_wait(CRYPTO_CONDVAR
*cv
, CRYPTO_MUTEX
*mutex
)
248 CONDITION_VARIABLE
*cv_p
;
249 CRITICAL_SECTION
*mutex_p
;
251 cv_p
= (CONDITION_VARIABLE
*)cv
;
252 mutex_p
= (CRITICAL_SECTION
*)mutex
;
253 SleepConditionVariableCS(cv_p
, mutex_p
, INFINITE
);
256 void ossl_crypto_condvar_wait_timeout(CRYPTO_CONDVAR
*cv
, CRYPTO_MUTEX
*mutex
,
260 CONDITION_VARIABLE
*cv_p
= (CONDITION_VARIABLE
*)cv
;
261 CRITICAL_SECTION
*mutex_p
= (CRITICAL_SECTION
*)mutex
;
263 if (!determine_timeout(deadline
, &timeout
))
266 SleepConditionVariableCS(cv_p
, mutex_p
, timeout
);
269 void ossl_crypto_condvar_broadcast(CRYPTO_CONDVAR
*cv
)
271 CONDITION_VARIABLE
*cv_p
;
273 cv_p
= (CONDITION_VARIABLE
*)cv
;
274 WakeAllConditionVariable(cv_p
);
277 void ossl_crypto_condvar_signal(CRYPTO_CONDVAR
*cv
)
279 CONDITION_VARIABLE
*cv_p
;
281 cv_p
= (CONDITION_VARIABLE
*)cv
;
282 WakeConditionVariable(cv_p
);
285 void ossl_crypto_condvar_free(CRYPTO_CONDVAR
**cv
)
287 CONDITION_VARIABLE
**cv_p
;
289 cv_p
= (CONDITION_VARIABLE
**)cv
;
296 void ossl_crypto_mem_barrier(void)