Reactos

[MSVCRT_SHARED] Implement TLS support for ucrtbase

+82
+1
dll/win32/msvcrt/CMakeLists.txt
··· 115 115 add_library(msvcrt_shared 116 116 ${SHARED_SOURCE} 117 117 ${msvcrt_shared_asm} 118 + reactos/ucrt_tls_sup.c 118 119 ) 119 120 120 121 target_compile_definitions(msvcrt_shared PRIVATE _MSVCR_VER=0 __UCRTSUPPORT__)
+81
dll/win32/msvcrt/reactos/ucrt_tls_sup.c
··· 1 + /* 2 + * PROJECT: ReactOS msvcrt 3 + * LICENSE: MIT (https://spdx.org/licenses/MIT) 4 + * PURPOSE: TLS support code for use with ucrtbase 5 + * COPYRIGHT: Copyright 2025 Timo Kreuzer <timo.kreuzer@reactos.org> 6 + */ 7 + 8 + #include <process.h> 9 + #include <assert.h> 10 + #include "msvcrt.h" 11 + #include "wine/debug.h" 12 + 13 + WINE_DEFAULT_DEBUG_CHANNEL(msvcrt); 14 + 15 + DWORD msvcrt_tls_index; 16 + 17 + BOOL msvcrt_init_tls(void) 18 + { 19 + msvcrt_tls_index = TlsAlloc(); 20 + if (msvcrt_tls_index == TLS_OUT_OF_INDEXES) 21 + { 22 + ERR("TlsAlloc() failed!\n"); 23 + return FALSE; 24 + } 25 + 26 + return TRUE; 27 + } 28 + 29 + BOOL msvcrt_free_tls(void) 30 + { 31 + if (!TlsFree(msvcrt_tls_index)) 32 + { 33 + ERR("TlsFree() failed!\n"); 34 + return FALSE; 35 + } 36 + 37 + return TRUE; 38 + } 39 + 40 + void msvcrt_free_tls_mem(void) 41 + { 42 + thread_data_t *tls = TlsGetValue(msvcrt_tls_index); 43 + if (tls) 44 + { 45 + free(tls->efcvt_buffer); 46 + assert(tls->asctime_buffer == NULL); 47 + assert(tls->wasctime_buffer == NULL); 48 + assert(tls->strerror_buffer == NULL); 49 + assert(tls->wcserror_buffer == NULL); 50 + assert(tls->time_buffer == NULL); 51 + assert(tls->tmpnam_buffer == NULL); 52 + assert(tls->wtmpnam_buffer == NULL); 53 + assert(tls->locinfo == NULL); 54 + assert(tls->mbcinfo == NULL); 55 + HeapFree(GetProcessHeap(), 0, tls); 56 + } 57 + } 58 + 59 + thread_data_t *CDECL msvcrt_get_thread_data(void) 60 + { 61 + thread_data_t *ptr; 62 + DWORD err = GetLastError(); /* need to preserve last error */ 63 + 64 + ptr = TlsGetValue(msvcrt_tls_index); 65 + if (ptr == NULL) 66 + { 67 + ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ptr)); 68 + if (ptr == NULL) 69 + exit(_RT_THREAD); 70 + 71 + if (!TlsSetValue(msvcrt_tls_index, ptr)) 72 + exit(_RT_THREAD); 73 + 74 + ptr->tid = GetCurrentThreadId(); 75 + ptr->handle = INVALID_HANDLE_VALUE; 76 + ptr->random_seed = 1; 77 + } 78 + 79 + SetLastError(err); 80 + return ptr; 81 + }