Signed-off-by: Nikolay Sivov nsivov@codeweavers.com ---
v2: removed todo_wine from ntdll tests.
dlls/kernel32/sync.c | 3 ++- dlls/kernel32/tests/sync.c | 14 +++++++++++- dlls/ntdll/critsection.c | 44 ++++++++++++++++++++++---------------- dlls/ntdll/tests/rtl.c | 1 - 4 files changed, 41 insertions(+), 21 deletions(-)
diff --git a/dlls/kernel32/sync.c b/dlls/kernel32/sync.c index 6d47d7004c..9f5b614508 100644 --- a/dlls/kernel32/sync.c +++ b/dlls/kernel32/sync.c @@ -402,7 +402,8 @@ void WINAPI MakeCriticalSectionGlobal( CRITICAL_SECTION *crit ) HANDLE sem = crit->LockSemaphore; if (!sem) NtCreateSemaphore( &sem, SEMAPHORE_ALL_ACCESS, NULL, 0, 1 ); crit->LockSemaphore = ConvertToGlobalHandle( sem ); - RtlFreeHeap( GetProcessHeap(), 0, crit->DebugInfo ); + if (crit->DebugInfo != (void *)(ULONG_PTR)-1) + RtlFreeHeap( GetProcessHeap(), 0, crit->DebugInfo ); crit->DebugInfo = NULL; }
diff --git a/dlls/kernel32/tests/sync.c b/dlls/kernel32/tests/sync.c index 188689a9f4..97566f1d84 100644 --- a/dlls/kernel32/tests/sync.c +++ b/dlls/kernel32/tests/sync.c @@ -2648,6 +2648,7 @@ static void test_crit_section(void) InitializeCriticalSection(&cs); ok(cs.DebugInfo != NULL, "Unexpected debug info pointer %p.\n", cs.DebugInfo); DeleteCriticalSection(&cs); + ok(cs.DebugInfo == NULL, "Unexpected debug info pointer %p.\n", cs.DebugInfo);
if (!pInitializeCriticalSectionEx) { @@ -2658,9 +2659,20 @@ static void test_crit_section(void) memset(&cs, 0, sizeof(cs)); ret = pInitializeCriticalSectionEx(&cs, 0, CRITICAL_SECTION_NO_DEBUG_INFO); ok(ret, "Failed to initialize critical section.\n"); -todo_wine ok(cs.DebugInfo == (void *)(ULONG_PTR)-1, "Unexpected debug info pointer %p.\n", cs.DebugInfo); + + ret = TryEnterCriticalSection(&cs); + ok(ret, "Failed to enter critical section.\n"); + LeaveCriticalSection(&cs); + + cs.DebugInfo = NULL; + + ret = TryEnterCriticalSection(&cs); + ok(ret, "Failed to enter critical section.\n"); + LeaveCriticalSection(&cs); + DeleteCriticalSection(&cs); + ok(cs.DebugInfo == NULL, "Unexpected debug info pointer %p.\n", cs.DebugInfo); }
START_TEST(sync) diff --git a/dlls/ntdll/critsection.c b/dlls/ntdll/critsection.c index 42e432c8f6..e8ffc1ceed 100644 --- a/dlls/ntdll/critsection.c +++ b/dlls/ntdll/critsection.c @@ -59,6 +59,13 @@ static inline void small_pause(void) #endif }
+static void *no_debug_info_marker = (void *)(ULONG_PTR)-1; + +static BOOL crit_section_has_debuginfo(const RTL_CRITICAL_SECTION *crit) +{ + return crit->DebugInfo != NULL && crit->DebugInfo != no_debug_info_marker; +} + #ifdef __linux__
static int wait_op = 128; /*FUTEX_WAIT|FUTEX_PRIVATE_FLAG*/ @@ -226,7 +233,7 @@ static inline NTSTATUS wait_semaphore( RTL_CRITICAL_SECTION *crit, int timeout ) NTSTATUS ret;
/* debug info is cleared by MakeCriticalSectionGlobal */ - if (!crit->DebugInfo || ((ret = fast_wait( crit, timeout )) == STATUS_NOT_IMPLEMENTED)) + if (!crit_section_has_debuginfo( crit ) || ((ret = fast_wait( crit, timeout )) == STATUS_NOT_IMPLEMENTED)) { HANDLE sem = get_semaphore( crit ); LARGE_INTEGER time; @@ -321,20 +328,21 @@ NTSTATUS WINAPI RtlInitializeCriticalSectionEx( RTL_CRITICAL_SECTION *crit, ULON * so (e.g.) MakeCriticalSectionGlobal() doesn't free it using HeapFree(). */ if (flags & RTL_CRITICAL_SECTION_FLAG_NO_DEBUG_INFO) - crit->DebugInfo = NULL; + crit->DebugInfo = no_debug_info_marker; else - crit->DebugInfo = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(RTL_CRITICAL_SECTION_DEBUG)); - - if (crit->DebugInfo) { - crit->DebugInfo->Type = 0; - crit->DebugInfo->CreatorBackTraceIndex = 0; - crit->DebugInfo->CriticalSection = crit; - crit->DebugInfo->ProcessLocksList.Blink = &(crit->DebugInfo->ProcessLocksList); - crit->DebugInfo->ProcessLocksList.Flink = &(crit->DebugInfo->ProcessLocksList); - crit->DebugInfo->EntryCount = 0; - crit->DebugInfo->ContentionCount = 0; - memset( crit->DebugInfo->Spare, 0, sizeof(crit->DebugInfo->Spare) ); + crit->DebugInfo = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(RTL_CRITICAL_SECTION_DEBUG)); + if (crit->DebugInfo) + { + crit->DebugInfo->Type = 0; + crit->DebugInfo->CreatorBackTraceIndex = 0; + crit->DebugInfo->CriticalSection = crit; + crit->DebugInfo->ProcessLocksList.Blink = &(crit->DebugInfo->ProcessLocksList); + crit->DebugInfo->ProcessLocksList.Flink = &(crit->DebugInfo->ProcessLocksList); + crit->DebugInfo->EntryCount = 0; + crit->DebugInfo->ContentionCount = 0; + memset( crit->DebugInfo->Spare, 0, sizeof(crit->DebugInfo->Spare) ); + } } crit->LockCount = -1; crit->RecursionCount = 0; @@ -396,7 +404,7 @@ NTSTATUS WINAPI RtlDeleteCriticalSection( RTL_CRITICAL_SECTION *crit ) crit->LockCount = -1; crit->RecursionCount = 0; crit->OwningThread = 0; - if (crit->DebugInfo) + if (crit_section_has_debuginfo( crit )) { /* only free the ones we made in here */ if (!crit->DebugInfo->Spare[0]) @@ -454,7 +462,7 @@ NTSTATUS WINAPI RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit ) if ( status == STATUS_TIMEOUT ) { const char *name = NULL; - if (crit->DebugInfo) name = (char *)crit->DebugInfo->Spare[0]; + if (crit_section_has_debuginfo( crit )) name = (char *)crit->DebugInfo->Spare[0]; if (!name) name = "?"; ERR( "section %p %s wait timed out in thread %04x, blocked by %04x, retrying (60 sec)\n", crit, debugstr_a(name), GetCurrentThreadId(), HandleToULong(crit->OwningThread) ); @@ -472,7 +480,7 @@ NTSTATUS WINAPI RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit ) if (status == STATUS_WAIT_0) break;
/* Throw exception only for Wine internal locks */ - if ((!crit->DebugInfo) || (!crit->DebugInfo->Spare[0])) continue; + if (!crit_section_has_debuginfo( crit ) || !crit->DebugInfo->Spare[0]) continue;
/* only throw deadlock exception if configured timeout is reached */ if (timeout > 0) continue; @@ -485,7 +493,7 @@ NTSTATUS WINAPI RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit ) rec.ExceptionInformation[0] = (ULONG_PTR)crit; RtlRaiseException( &rec ); } - if (crit->DebugInfo) crit->DebugInfo->ContentionCount++; + if (crit_section_has_debuginfo( crit )) crit->DebugInfo->ContentionCount++; return STATUS_SUCCESS; }
@@ -518,7 +526,7 @@ NTSTATUS WINAPI RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit ) NTSTATUS ret;
/* debug info is cleared by MakeCriticalSectionGlobal */ - if (!crit->DebugInfo || ((ret = fast_wake( crit )) == STATUS_NOT_IMPLEMENTED)) + if (!crit_section_has_debuginfo( crit ) || ((ret = fast_wake( crit )) == STATUS_NOT_IMPLEMENTED)) { HANDLE sem = get_semaphore( crit ); ret = NtReleaseSemaphore( sem, 1, NULL ); diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c index 5fe72ec38b..62662cb438 100644 --- a/dlls/ntdll/tests/rtl.c +++ b/dlls/ntdll/tests/rtl.c @@ -3152,7 +3152,6 @@ static void test_RtlInitializeCriticalSectionEx(void)
memset(&cs, 0x11, sizeof(cs)); pRtlInitializeCriticalSectionEx(&cs, 0, RTL_CRITICAL_SECTION_FLAG_NO_DEBUG_INFO); - todo_wine ok(cs.DebugInfo == no_debug, "expected DebugInfo == ~0, got %p\n", cs.DebugInfo); ok(cs.LockCount == -1, "expected LockCount == -1, got %d\n", cs.LockCount); ok(cs.RecursionCount == 0, "expected RecursionCount == 0, got %d\n", cs.RecursionCount);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=51630
Your paranoid android.
=== debian9 (32 bit report) ===
ntdll: pipe.c:1557: Test failed: pipe is not signaled pipe.c:1557: Test failed: pipe is not signaled
=== debian9 (32 bit Chinese:China report) ===
ntdll: pipe.c:1557: Test failed: pipe is not signaled pipe.c:1557: Test failed: pipe is not signaled