Paul Gofman : ntdll: Increment num_busy_workers when queuing TP object.

Alexandre Julliard julliard at winehq.org
Mon Jun 22 15:55:57 CDT 2020


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

Author: Paul Gofman <pgofman at codeweavers.com>
Date:   Fri Jun 19 19:05:39 2020 +0300

ntdll: Increment num_busy_workers when queuing TP object.

Otherwise two consequative submits may have the same
num_busy_workers value if threadpool_worker_proc did not
have a chance to pick the work in between. A new thread is
not created in tp_submit() for the second submit and if the
first submit queues an (infinitely long) wait
the next submitted callback is not called for indefinite
time period.

Fixes hang on exit in Detroit Become Human.

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

---

 dlls/ntdll/threadpool.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c
index 451d441f57..84286fbee9 100644
--- a/dlls/ntdll/threadpool.c
+++ b/dlls/ntdll/threadpool.c
@@ -1375,7 +1375,6 @@ static NTSTATUS tp_new_worker_thread( struct threadpool *pool )
     {
         InterlockedIncrement( &pool->refcount );
         pool->num_workers++;
-        pool->num_busy_workers++;
         NtClose( thread );
     }
     return status;
@@ -2137,6 +2136,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa
 
 static void tp_object_prio_queue( struct threadpool_object *object )
 {
+    ++object->pool->num_busy_workers;
     list_add_tail( &object->pool->pools[object->priority], &object->pool_entry );
 }
 
@@ -2330,7 +2330,6 @@ static void CALLBACK threadpool_worker_proc( void *param )
     TRACE( "starting worker thread for pool %p\n", pool );
 
     RtlEnterCriticalSection( &pool->cs );
-    pool->num_busy_workers--;
     for (;;)
     {
         while ((ptr = threadpool_get_next_item( pool )))
@@ -2360,7 +2359,6 @@ static void CALLBACK threadpool_worker_proc( void *param )
             /* Leave critical section and do the actual callback. */
             object->num_associated_callbacks++;
             object->num_running_callbacks++;
-            pool->num_busy_workers++;
             RtlLeaveCriticalSection( &pool->cs );
 
             /* Initialize threadpool instance struct. */
@@ -2466,6 +2464,7 @@ static void CALLBACK threadpool_worker_proc( void *param )
 
         skip_cleanup:
             RtlEnterCriticalSection( &pool->cs );
+            assert(pool->num_busy_workers);
             pool->num_busy_workers--;
 
             /* Simple callbacks are automatically shutdown after execution. */




More information about the wine-cvs mailing list