ntdll: Introduce new tp_object_execute helper.

To execute a threadpool_object callbacks.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47843
Signed-off-by: Rémi Bernon <rbernon@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Rémi Bernon 2021-02-11 10:53:48 +01:00 committed by Alexandre Julliard
parent 3ed3e031ff
commit 304d811924
1 changed files with 160 additions and 143 deletions

View File

@ -372,6 +372,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_execute( 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;
@ -2095,34 +2096,21 @@ static struct list *threadpool_get_next_item( const struct threadpool *pool )
}
/***********************************************************************
* threadpool_worker_proc (internal)
* tp_object_execute (internal)
*
* Executes a threadpool object callback, object->pool->cs has to be
* held.
*/
static void CALLBACK threadpool_worker_proc( void *param )
static void tp_object_execute( struct threadpool_object *object )
{
TP_CALLBACK_INSTANCE *callback_instance;
struct threadpool_instance instance;
struct io_completion completion;
struct threadpool *pool = param;
struct threadpool *pool = object->pool;
TP_WAIT_RESULT wait_result = 0;
LARGE_INTEGER timeout;
struct list *ptr;
NTSTATUS status;
TRACE( "starting worker thread for pool %p\n", pool );
RtlEnterCriticalSection( &pool->cs );
for (;;)
{
while ((ptr = threadpool_get_next_item( pool )))
{
struct threadpool_object *object = LIST_ENTRY( ptr, struct threadpool_object, pool_entry );
assert( object->num_pending_callbacks > 0 );
/* If further pending callbacks are queued, move the work item to
* the end of the pool list. Otherwise remove it from the pool. */
list_remove( &object->pool_entry );
if (--object->num_pending_callbacks)
tp_object_prio_queue( object );
object->num_pending_callbacks--;
/* For wait objects check if they were signaled or have timed out. */
if (object->type == TP_OBJECT_TYPE_WAIT)
@ -2245,8 +2233,6 @@ 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. */
if (object->type == TP_OBJECT_TYPE_SIMPLE)
@ -2265,6 +2251,37 @@ static void CALLBACK threadpool_worker_proc( void *param )
if (object_is_finished( object, FALSE ))
RtlWakeAllConditionVariable( &object->finished_event );
}
}
/***********************************************************************
* threadpool_worker_proc (internal)
*/
static void CALLBACK threadpool_worker_proc( void *param )
{
struct threadpool *pool = param;
LARGE_INTEGER timeout;
struct list *ptr;
TRACE( "starting worker thread for pool %p\n", pool );
RtlEnterCriticalSection( &pool->cs );
for (;;)
{
while ((ptr = threadpool_get_next_item( pool )))
{
struct threadpool_object *object = LIST_ENTRY( ptr, struct threadpool_object, pool_entry );
assert( object->num_pending_callbacks > 0 );
/* If further pending callbacks are queued, move the work item to
* the end of the pool list. Otherwise remove it from the pool. */
list_remove( &object->pool_entry );
if (object->num_pending_callbacks > 1)
tp_object_prio_queue( object );
tp_object_execute( object );
assert(pool->num_busy_workers);
pool->num_busy_workers--;
tp_object_release( object );
}