Commit 53db77b5 authored by Sebastian Lackner's avatar Sebastian Lackner Committed by Alexandre Julliard

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

parent 914d597e
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Thread pooling * Thread pooling
* *
* Copyright (c) 2006 Robert Shearman * 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 * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * 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 ...@@ -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 CALLBACK threadpool_worker_proc( void *param );
static void tp_object_submit( struct threadpool_object *object, BOOL signaled ); 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 BOOL tp_object_release( struct threadpool_object *object );
static struct threadpool *default_threadpool = NULL; static struct threadpool *default_threadpool = NULL;
...@@ -1886,7 +1886,8 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa ...@@ -1886,7 +1886,8 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa
if (is_simple_callback) if (is_simple_callback)
{ {
tp_object_shutdown( object ); tp_object_prepare_shutdown( object );
object->shutdown = TRUE;
tp_object_release( object ); tp_object_release( object );
} }
} }
...@@ -2001,19 +2002,16 @@ static void tp_object_wait( struct threadpool_object *object, BOOL group_wait ) ...@@ -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 * Prepares a threadpool object for shutdown.
* tasks can be submitted).
*/ */
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) if (object->type == TP_OBJECT_TYPE_TIMER)
tp_timerqueue_unlock( object ); tp_timerqueue_unlock( object );
else if (object->type == TP_OBJECT_TYPE_WAIT) else if (object->type == TP_OBJECT_TYPE_WAIT)
tp_waitqueue_unlock( object ); tp_waitqueue_unlock( object );
object->shutdown = TRUE;
} }
/*********************************************************************** /***********************************************************************
...@@ -2574,10 +2572,6 @@ VOID WINAPI TpReleaseCleanupGroupMembers( TP_CLEANUP_GROUP *group, BOOL cancel_p ...@@ -2574,10 +2572,6 @@ VOID WINAPI TpReleaseCleanupGroupMembers( TP_CLEANUP_GROUP *group, BOOL cancel_p
assert( object->group == this ); assert( object->group == this );
assert( object->is_group_member ); 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 /* Object is basically already destroyed, but group reference
...@@ -2587,10 +2581,9 @@ VOID WINAPI TpReleaseCleanupGroupMembers( TP_CLEANUP_GROUP *group, BOOL cancel_p ...@@ -2587,10 +2581,9 @@ VOID WINAPI TpReleaseCleanupGroupMembers( TP_CLEANUP_GROUP *group, BOOL cancel_p
object->is_group_member = FALSE; object->is_group_member = FALSE;
continue; continue;
} }
}
object->is_group_member = FALSE; object->is_group_member = FALSE;
tp_object_shutdown( object ); tp_object_prepare_shutdown( object );
} }
/* Move members to a new temporary list */ /* Move members to a new temporary list */
...@@ -2612,6 +2605,11 @@ VOID WINAPI TpReleaseCleanupGroupMembers( TP_CLEANUP_GROUP *group, BOOL cancel_p ...@@ -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 ) LIST_FOR_EACH_ENTRY_SAFE( object, next, &members, struct threadpool_object, group_entry )
{ {
tp_object_wait( object, TRUE ); 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 ); tp_object_release( object );
} }
} }
...@@ -2638,7 +2636,8 @@ VOID WINAPI TpReleaseTimer( TP_TIMER *timer ) ...@@ -2638,7 +2636,8 @@ VOID WINAPI TpReleaseTimer( TP_TIMER *timer )
TRACE( "%p\n", timer ); TRACE( "%p\n", timer );
tp_object_shutdown( this ); tp_object_prepare_shutdown( this );
this->shutdown = TRUE;
tp_object_release( this ); tp_object_release( this );
} }
...@@ -2651,7 +2650,8 @@ VOID WINAPI TpReleaseWait( TP_WAIT *wait ) ...@@ -2651,7 +2650,8 @@ VOID WINAPI TpReleaseWait( TP_WAIT *wait )
TRACE( "%p\n", wait ); TRACE( "%p\n", wait );
tp_object_shutdown( this ); tp_object_prepare_shutdown( this );
this->shutdown = TRUE;
tp_object_release( this ); tp_object_release( this );
} }
...@@ -2664,7 +2664,8 @@ VOID WINAPI TpReleaseWork( TP_WORK *work ) ...@@ -2664,7 +2664,8 @@ VOID WINAPI TpReleaseWork( TP_WORK *work )
TRACE( "%p\n", work ); TRACE( "%p\n", work );
tp_object_shutdown( this ); tp_object_prepare_shutdown( this );
this->shutdown = TRUE;
tp_object_release( this ); tp_object_release( this );
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment