From 4039c5ad47a999a771120091ca57d087b01ee382 Mon Sep 17 00:00:00 2001 From: Paul Gofman Date: Tue, 6 Oct 2020 13:04:50 +0300 Subject: [PATCH] ntdll: Don't use PEB lock for FLS data. Signed-off-by: Paul Gofman Signed-off-by: Alexandre Julliard --- dlls/kernel32/tests/fiber.c | 36 +++++++++++++++++++++++++++++++++--- dlls/ntdll/thread.c | 13 +++++++++++-- 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/dlls/kernel32/tests/fiber.c b/dlls/kernel32/tests/fiber.c index 336d913c547..30f9152c39e 100644 --- a/dlls/kernel32/tests/fiber.c +++ b/dlls/kernel32/tests/fiber.c @@ -37,6 +37,8 @@ static DWORD (WINAPI *pFlsAlloc)(PFLS_CALLBACK_FUNCTION); static BOOL (WINAPI *pFlsFree)(DWORD); static PVOID (WINAPI *pFlsGetValue)(DWORD); static BOOL (WINAPI *pFlsSetValue)(DWORD,PVOID); +static void (WINAPI *pRtlAcquirePebLock)(void); +static void (WINAPI *pRtlReleasePebLock)(void); static NTSTATUS (WINAPI *pRtlFlsAlloc)(PFLS_CALLBACK_FUNCTION,DWORD*); static NTSTATUS (WINAPI *pRtlFlsFree)(ULONG); static NTSTATUS (WINAPI *pRtlFlsSetValue)(ULONG,void *); @@ -76,6 +78,8 @@ static VOID init_funcs(void) X(RtlFlsSetValue); X(RtlFlsGetValue); X(RtlProcessFlsData); + X(RtlAcquirePebLock); + X(RtlReleasePebLock); #undef X } @@ -239,6 +243,19 @@ static unsigned int test_fls_chunk_index_from_index(unsigned int index, unsigned return chunk_index; } +static HANDLE test_fiberlocalstorage_peb_locked_event; +static HANDLE test_fiberlocalstorage_done_event; + + +static DWORD WINAPI test_FiberLocalStorage_thread(void *arg) +{ + pRtlAcquirePebLock(); + SetEvent(test_fiberlocalstorage_peb_locked_event); + WaitForSingleObject(test_fiberlocalstorage_done_event, INFINITE); + pRtlReleasePebLock(); + return 0; +} + static void test_FiberLocalStorage(void) { static DWORD fls_indices[FLS_TEST_INDEX_COUNT]; @@ -246,10 +263,11 @@ static void test_FiberLocalStorage(void) LIST_ENTRY *fls_list_head, saved_entry; TEB_FLS_DATA *fls_data, *new_fls_data; GLOBAL_FLS_DATA *g_fls_data; + DWORD fls, fls_2, result; TEB *teb = NtCurrentTeb(); PEB *peb = teb->Peb; - DWORD fls, fls_2; NTSTATUS status; + HANDLE hthread; SIZE_T size; void* val; BOOL ret; @@ -424,17 +442,29 @@ static void test_FiberLocalStorage(void) HeapSize(GetProcessHeap(), 0, new_fls_data); } - saved_entry = new_fls_data->fls_list_entry; + test_fiberlocalstorage_peb_locked_event = CreateEventA(NULL, FALSE, FALSE, NULL); + test_fiberlocalstorage_done_event = CreateEventA(NULL, FALSE, FALSE, NULL); + hthread = CreateThread(NULL, 0, test_FiberLocalStorage_thread, NULL, 0, NULL); + ok(!!hthread, "CreateThread failed.\n"); + result = WaitForSingleObject(test_fiberlocalstorage_peb_locked_event, INFINITE); + ok(result == WAIT_OBJECT_0, "Got unexpected result %u.\n", result); teb->FlsSlots = NULL; + + saved_entry = new_fls_data->fls_list_entry; pRtlProcessFlsData(new_fls_data, 1); ok(!teb->FlsSlots, "Got unexpected teb->FlsSlots %p.\n", teb->FlsSlots); + teb->FlsSlots = fls_data; + SetEvent(test_fiberlocalstorage_done_event); + WaitForSingleObject(hthread, INFINITE); + CloseHandle(hthread); + CloseHandle(test_fiberlocalstorage_peb_locked_event); + CloseHandle(test_fiberlocalstorage_done_event); ok(new_fls_data->fls_list_entry.Flink == saved_entry.Flink, "Got unexpected Flink %p.\n", saved_entry.Flink); ok(new_fls_data->fls_list_entry.Blink == saved_entry.Blink, "Got unexpected Flink %p.\n", saved_entry.Blink); - size = HeapSize(GetProcessHeap(), 0, new_fls_data); ok(size == sizeof(*new_fls_data), "Got unexpected size %p.\n", (void *)size); pRtlProcessFlsData(new_fls_data, 2); diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index 822dc21fbbc..cf6bddab0b4 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -256,6 +256,15 @@ TEB_ACTIVE_FRAME * WINAPI RtlGetFrame(void) static GLOBAL_FLS_DATA fls_data; +static RTL_CRITICAL_SECTION fls_section; +static RTL_CRITICAL_SECTION_DEBUG fls_critsect_debug = +{ + 0, 0, &fls_section, + { &fls_critsect_debug.ProcessLocksList, &fls_critsect_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": fls_section") } +}; +static RTL_CRITICAL_SECTION fls_section = { &fls_critsect_debug, -1, 0, 0, 0, 0 }; + #define MAX_FLS_DATA_COUNT 0xff0 void init_global_fls_data(void) @@ -265,12 +274,12 @@ void init_global_fls_data(void) static void lock_fls_data(void) { - RtlAcquirePebLock(); + RtlEnterCriticalSection( &fls_section ); } static void unlock_fls_data(void) { - RtlReleasePebLock(); + RtlLeaveCriticalSection( &fls_section ); } static unsigned int fls_chunk_size( unsigned int chunk_index )