Fix a couple of errors.

This commit is contained in:
Zebediah Figura
2020-05-04 22:44:11 -05:00
parent 76ba9d2387
commit 3e39e3132b
2 changed files with 28 additions and 19 deletions

View File

@ -1,4 +1,4 @@
From 91a597b6a9299483c29c2d79b7471735b3839009 Mon Sep 17 00:00:00 2001
From f8e12f51bebca8cda3be339bcc216ca8cc60a718 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Wed, 25 Feb 2015 22:45:42 +0100
Subject: [PATCH] ntdll: Fix race-condition when threads are killed during
@ -15,14 +15,14 @@ only be executed safely when all other threads have terminated before. Most
likely there are more Wine bugs in this area, but the attached patch should
fix the most critical one (messed up refcounting of threads) for now.
---
dlls/ntdll/thread.c | 6 ++++++
1 file changed, 6 insertions(+)
dlls/ntdll/thread.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index eda5d1cea12b..8a0b612b39a4 100644
index b25f87e437..5fbd9e06c3 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -429,6 +429,7 @@ void exit_thread( int status )
@@ -336,6 +336,7 @@ void exit_thread( int status )
void WINAPI RtlExitUserThread( ULONG status )
{
static void *prev_teb;
@ -30,14 +30,23 @@ index eda5d1cea12b..8a0b612b39a4 100644
TEB *teb;
if (status) /* send the exit code to the server (0 is already the default) */
@@ -465,6 +466,11 @@ void WINAPI RtlExitUserThread( ULONG status )
@@ -349,7 +350,7 @@ void WINAPI RtlExitUserThread( ULONG status )
SERVER_END_REQ;
}
- if (InterlockedDecrement( &nb_threads ) <= 0)
+ if (InterlockedCompareExchange( &nb_threads, 0, 0 ) <= 0)
{
LdrShutdownProcess();
pthread_sigmask( SIG_BLOCK, &server_block_set, NULL );
@@ -372,6 +373,11 @@ void WINAPI RtlExitUserThread( ULONG status )
}
}
+ sigemptyset( &sigset );
+ sigaddset( &sigset, SIGQUIT );
+ pthread_sigmask( SIG_BLOCK, &sigset, NULL );
+ if (InterlockedDecrement( &nb_threads ) <= 1) _exit( status );
+ if (!InterlockedDecrement( &nb_threads )) _exit( status );
+
signal_exit_thread( status );
}