Paul Gofman : ntdll: Don't use PEB lock for FLS data.

Alexandre Julliard julliard at winehq.org
Thu Oct 8 15:20:05 CDT 2020


Module: wine
Branch: master
Commit: 4039c5ad47a999a771120091ca57d087b01ee382
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=4039c5ad47a999a771120091ca57d087b01ee382

Author: Paul Gofman <pgofman at codeweavers.com>
Date:   Tue Oct  6 13:04:50 2020 +0300

ntdll: Don't use PEB lock for FLS data.

Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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 336d913c54..30f9152c39 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 822dc21fbb..cf6bddab0b 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 )




More information about the wine-cvs mailing list