17 #if defined(OPENSSL_WINDOWS_THREADS)
31 "CRYPTO_MUTEX is too small");
32 #if defined(__GNUC__) || defined(__clang__)
34 "CRYPTO_MUTEX has insufficient alignment");
37 static BOOL CALLBACK call_once_init(INIT_ONCE *
once,
void *
arg,
void **
out) {
38 void (**
init)(void) = (
void (**)(void))
arg;
44 if (!InitOnceExecuteOnce(
once, call_once_init, &
init, NULL)) {
50 InitializeSRWLock((
SRWLOCK *) lock);
54 AcquireSRWLockShared((
SRWLOCK *) lock);
58 AcquireSRWLockExclusive((
SRWLOCK *) lock);
62 ReleaseSRWLockShared((
SRWLOCK *) lock);
66 ReleaseSRWLockExclusive((
SRWLOCK *) lock);
74 AcquireSRWLockShared(&lock->lock);
78 AcquireSRWLockExclusive(&lock->lock);
82 ReleaseSRWLockShared(&lock->lock);
86 ReleaseSRWLockExclusive(&lock->lock);
89 static SRWLOCK g_destructors_lock = SRWLOCK_INIT;
93 static DWORD g_thread_local_key;
94 static int g_thread_local_failed;
96 static void thread_local_init(
void) {
97 g_thread_local_key = TlsAlloc();
98 g_thread_local_failed = (g_thread_local_key == TLS_OUT_OF_INDEXES);
101 static void NTAPI thread_local_destructor(PVOID
module, DWORD reason,
108 if (reason != DLL_THREAD_DETACH) {
112 CRYPTO_once(&g_thread_local_init_once, thread_local_init);
113 if (g_thread_local_failed) {
117 void **pointers = (
void**) TlsGetValue(g_thread_local_key);
118 if (pointers == NULL) {
124 AcquireSRWLockExclusive(&g_destructors_lock);
126 ReleaseSRWLockExclusive(&g_destructors_lock);
129 if (destructors[
i] != NULL) {
130 destructors[
i](pointers[
i]);
150 #define STRINGIFY(x) #x
151 #define EXPAND_AND_STRINGIFY(x) STRINGIFY(x)
153 __pragma(comment(linker,
"/INCLUDE:_tls_used"))
155 linker, "/INCLUDE:" EXPAND_AND_STRINGIFY(p_thread_callback_boringssl)))
157 __pragma(comment(linker,
"/INCLUDE:__tls_used"))
159 linker, "/INCLUDE:
_" EXPAND_AND_STRINGIFY(p_thread_callback_boringssl)))
181 #pragma const_seg(".CRT$XLC")
184 extern const PIMAGE_TLS_CALLBACK p_thread_callback_boringssl;
185 const PIMAGE_TLS_CALLBACK p_thread_callback_boringssl = thread_local_destructor;
191 #pragma data_seg(".CRT$XLC")
192 PIMAGE_TLS_CALLBACK p_thread_callback_boringssl = thread_local_destructor;
198 static void **get_thread_locals(
void) {
210 DWORD last_error = GetLastError();
211 void **
ret = TlsGetValue(g_thread_local_key);
212 SetLastError(last_error);
217 CRYPTO_once(&g_thread_local_init_once, thread_local_init);
218 if (g_thread_local_failed) {
222 void **pointers = get_thread_locals();
223 if (pointers == NULL) {
226 return pointers[
index];
231 CRYPTO_once(&g_thread_local_init_once, thread_local_init);
232 if (g_thread_local_failed) {
237 void **pointers = get_thread_locals();
238 if (pointers == NULL) {
240 if (pointers == NULL) {
245 if (TlsSetValue(g_thread_local_key, pointers) == 0) {
252 AcquireSRWLockExclusive(&g_destructors_lock);
253 g_destructors[
index] = destructor;
254 ReleaseSRWLockExclusive(&g_destructors_lock);
260 #endif // OPENSSL_WINDOWS_THREADS