[PATCH 2/2] ntdll: Don't allow blocking on a critical section during process termination.
Dmitry Timoshkov
dmitry at baikal.ru
Tue Aug 7 03:03:16 CDT 2018
As a result HeapLock() no longer blocks process termination since underlying
implementation uses a critical section. However this should be considered as
a minor side effect because applications shouldn't depend on this behaviour.
This patch should fix the deadlocks observered during various .net setups,
and it appears that this is what Windows does as well.
Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
---
dlls/kernel32/tests/loader.c | 4 +++-
dlls/ntdll/critsection.c | 9 +++++++++
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/dlls/kernel32/tests/loader.c b/dlls/kernel32/tests/loader.c
index 46c09d41cb..e4d6741b6f 100644
--- a/dlls/kernel32/tests/loader.c
+++ b/dlls/kernel32/tests/loader.c
@@ -2169,6 +2169,7 @@ static BOOL WINAPI dll_entry_point(HINSTANCE hinst, DWORD reason, LPVOID param)
* doesn't call the DLL entry point on process detach either.
*/
HeapLock(GetProcessHeap());
+todo_wine
ok(0, "dll_entry_point: process should already deadlock\n");
break;
}
@@ -3023,6 +3024,7 @@ static void test_ExitProcess(void)
ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
ok(ret, "CreateProcess(%s) error %d\n", cmdline, GetLastError());
ret = WaitForSingleObject(pi.hProcess, 5000);
+todo_wine
ok(ret == WAIT_TIMEOUT || broken(ret == WAIT_OBJECT_0) /* XP */, "child process should fail to terminate\n");
if (ret != WAIT_OBJECT_0)
{
@@ -3032,6 +3034,7 @@ static void test_ExitProcess(void)
ret = WaitForSingleObject(pi.hProcess, 1000);
ok(ret == WAIT_OBJECT_0, "child process failed to terminate\n");
GetExitCodeProcess(pi.hProcess, &ret);
+todo_wine
ok(ret == 201 || broken(ret == 1) /* XP */, "expected exit code 201, got %u\n", ret);
if (*child_failures)
{
@@ -3047,7 +3050,6 @@ static void test_ExitProcess(void)
ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
ok(ret, "CreateProcess(%s) error %d\n", cmdline, GetLastError());
ret = WaitForSingleObject(pi.hProcess, 5000);
-todo_wine
ok(ret == WAIT_OBJECT_0, "child process failed to terminate\n");
if (ret != WAIT_OBJECT_0)
{
diff --git a/dlls/ntdll/critsection.c b/dlls/ntdll/critsection.c
index e405b08a5a..42e432c8f6 100644
--- a/dlls/ntdll/critsection.c
+++ b/dlls/ntdll/critsection.c
@@ -436,6 +436,15 @@ NTSTATUS WINAPI RtlDeleteCriticalSection( RTL_CRITICAL_SECTION *crit )
NTSTATUS WINAPI RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit )
{
LONGLONG timeout = NtCurrentTeb()->Peb->CriticalSectionTimeout.QuadPart / -10000000;
+
+ /* Don't allow blocking on a critical section during process termination */
+ if (RtlDllShutdownInProgress())
+ {
+ WARN( "process %s is shutting down, returning STATUS_SUCCESS\n",
+ debugstr_w(NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer) );
+ return STATUS_SUCCESS;
+ }
+
for (;;)
{
EXCEPTION_RECORD rec;
--
2.17.1
More information about the wine-devel
mailing list