Sebastian Lackner : ntdll: Allow to release threadpool objects while waiting for group.

Alexandre Julliard julliard at winehq.org
Mon Aug 22 10:24:12 CDT 2016


Module: wine
Branch: master
Commit: 53db77b5d7a16865069dd4eca83864bf48bbcc11
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=53db77b5d7a16865069dd4eca83864bf48bbcc11

Author: Sebastian Lackner <sebastian at fds-team.de>
Date:   Sat Aug 20 21:22:29 2016 +0200

ntdll: Allow to release threadpool objects while waiting for group.

Signed-off-by: Sebastian Lackner <sebastian at fds-team.de>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/threadpool.c | 51 +++++++++++++++++++++++++------------------------
 1 file changed, 26 insertions(+), 25 deletions(-)

diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c
index 5d5b49d..eea5a88 100644
--- a/dlls/ntdll/threadpool.c
+++ b/dlls/ntdll/threadpool.c
@@ -2,7 +2,7 @@
  * Thread pooling
  *
  * Copyright (c) 2006 Robert Shearman
- * Copyright (c) 2014-2015 Sebastian Lackner
+ * Copyright (c) 2014-2016 Sebastian Lackner
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -327,7 +327,7 @@ static inline struct threadpool_instance *impl_from_TP_CALLBACK_INSTANCE( TP_CAL
 
 static void CALLBACK threadpool_worker_proc( void *param );
 static void tp_object_submit( struct threadpool_object *object, BOOL signaled );
-static void tp_object_shutdown( struct threadpool_object *object );
+static void tp_object_prepare_shutdown( struct threadpool_object *object );
 static BOOL tp_object_release( struct threadpool_object *object );
 static struct threadpool *default_threadpool = NULL;
 
@@ -1886,7 +1886,8 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa
 
     if (is_simple_callback)
     {
-        tp_object_shutdown( object );
+        tp_object_prepare_shutdown( object );
+        object->shutdown = TRUE;
         tp_object_release( object );
     }
 }
@@ -2001,19 +2002,16 @@ static void tp_object_wait( struct threadpool_object *object, BOOL group_wait )
 }
 
 /***********************************************************************
- *           tp_object_shutdown    (internal)
+ *           tp_object_prepare_shutdown    (internal)
  *
- * Marks a threadpool object for shutdown (which means that no further
- * tasks can be submitted).
+ * Prepares a threadpool object for shutdown.
  */
-static void tp_object_shutdown( struct threadpool_object *object )
+static void tp_object_prepare_shutdown( struct threadpool_object *object )
 {
     if (object->type == TP_OBJECT_TYPE_TIMER)
         tp_timerqueue_unlock( object );
     else if (object->type == TP_OBJECT_TYPE_WAIT)
         tp_waitqueue_unlock( object );
-
-    object->shutdown = TRUE;
 }
 
 /***********************************************************************
@@ -2574,23 +2572,18 @@ VOID WINAPI TpReleaseCleanupGroupMembers( TP_CLEANUP_GROUP *group, BOOL cancel_p
         assert( object->group == this );
         assert( object->is_group_member );
 
-        /* Simple callbacks are very special. The user doesn't hold any reference, so
-         * they would be released too early. Add one additional temporary reference. */
-        if (object->type == TP_OBJECT_TYPE_SIMPLE)
+        if (interlocked_inc( &object->refcount ) == 1)
         {
-            if (interlocked_inc( &object->refcount ) == 1)
-            {
-                /* Object is basically already destroyed, but group reference
-                 * was not deleted yet. We can safely ignore this object. */
-                interlocked_dec( &object->refcount );
-                list_remove( &object->group_entry );
-                object->is_group_member = FALSE;
-                continue;
-            }
+            /* Object is basically already destroyed, but group reference
+             * was not deleted yet. We can safely ignore this object. */
+            interlocked_dec( &object->refcount );
+            list_remove( &object->group_entry );
+            object->is_group_member = FALSE;
+            continue;
         }
 
         object->is_group_member = FALSE;
-        tp_object_shutdown( object );
+        tp_object_prepare_shutdown( object );
     }
 
     /* Move members to a new temporary list */
@@ -2612,6 +2605,11 @@ VOID WINAPI TpReleaseCleanupGroupMembers( TP_CLEANUP_GROUP *group, BOOL cancel_p
     LIST_FOR_EACH_ENTRY_SAFE( object, next, &members, struct threadpool_object, group_entry )
     {
         tp_object_wait( object, TRUE );
+
+        if (object->type != TP_OBJECT_TYPE_SIMPLE && !object->shutdown)
+            tp_object_release( object );
+
+        object->shutdown = TRUE;
         tp_object_release( object );
     }
 }
@@ -2638,7 +2636,8 @@ VOID WINAPI TpReleaseTimer( TP_TIMER *timer )
 
     TRACE( "%p\n", timer );
 
-    tp_object_shutdown( this );
+    tp_object_prepare_shutdown( this );
+    this->shutdown = TRUE;
     tp_object_release( this );
 }
 
@@ -2651,7 +2650,8 @@ VOID WINAPI TpReleaseWait( TP_WAIT *wait )
 
     TRACE( "%p\n", wait );
 
-    tp_object_shutdown( this );
+    tp_object_prepare_shutdown( this );
+    this->shutdown = TRUE;
     tp_object_release( this );
 }
 
@@ -2664,7 +2664,8 @@ VOID WINAPI TpReleaseWork( TP_WORK *work )
 
     TRACE( "%p\n", work );
 
-    tp_object_shutdown( this );
+    tp_object_prepare_shutdown( this );
+    this->shutdown = TRUE;
     tp_object_release( this );
 }
 




More information about the wine-cvs mailing list