mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
143 lines
5.1 KiB
Diff
143 lines
5.1 KiB
Diff
From 696ecf266d29fb3120a1348a47fe55e65da2f0d6 Mon Sep 17 00:00:00 2001
|
|
From: Sebastian Lackner <sebastian@fds-team.de>
|
|
Date: Sat, 20 Aug 2016 21:22:29 +0200
|
|
Subject: ntdll: Allow to release threadpool objects while waiting for group.
|
|
|
|
Signed-off-by: Sebastian Lackner <sebastian@fds-team.de>
|
|
---
|
|
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 );
|
|
}
|
|
|
|
--
|
|
2.9.0
|
|
|