Commit 288814a4 authored by Dmitry Timoshkov's avatar Dmitry Timoshkov Committed by Alexandre Julliard

server: Make it possible to deliver an APC to any thread alive in the process.

parent 5350eea7
...@@ -167,7 +167,7 @@ void async_terminate( struct async *async, unsigned int status ) ...@@ -167,7 +167,7 @@ void async_terminate( struct async *async, unsigned int status )
data.async_io.user = async->data.user; data.async_io.user = async->data.user;
data.async_io.sb = async->data.iosb; data.async_io.sb = async->data.iosb;
data.async_io.status = status; data.async_io.status = status;
thread_queue_apc( async->thread, &async->obj, &data ); thread_queue_apc( NULL, async->thread, &async->obj, &data );
} }
else async_set_result( &async->obj, STATUS_SUCCESS, 0 ); else async_set_result( &async->obj, STATUS_SUCCESS, 0 );
} }
...@@ -373,7 +373,7 @@ void async_set_result( struct object *obj, unsigned int status, apc_param_t tota ...@@ -373,7 +373,7 @@ void async_set_result( struct object *obj, unsigned int status, apc_param_t tota
data.user.args[0] = async->data.apc_context; data.user.args[0] = async->data.apc_context;
data.user.args[1] = async->data.iosb; data.user.args[1] = async->data.iosb;
data.user.args[2] = 0; data.user.args[2] = 0;
thread_queue_apc( async->thread, NULL, &data ); thread_queue_apc( NULL, async->thread, NULL, &data );
} }
else if (async->data.apc_context) else if (async->data.apc_context)
add_async_completion( async, async->data.apc_context, status, total ); add_async_completion( async, async->data.apc_context, status, total );
......
...@@ -926,6 +926,9 @@ static int queue_apc( struct process *process, struct thread *thread, struct thr ...@@ -926,6 +926,9 @@ static int queue_apc( struct process *process, struct thread *thread, struct thr
{ {
struct list *queue; struct list *queue;
if (thread && thread->state == TERMINATED && process)
thread = NULL;
if (!thread) /* find a suitable thread inside the process */ if (!thread) /* find a suitable thread inside the process */
{ {
struct thread *candidate; struct thread *candidate;
...@@ -977,14 +980,14 @@ static int queue_apc( struct process *process, struct thread *thread, struct thr ...@@ -977,14 +980,14 @@ static int queue_apc( struct process *process, struct thread *thread, struct thr
} }
/* queue an async procedure call */ /* queue an async procedure call */
int thread_queue_apc( struct thread *thread, struct object *owner, const apc_call_t *call_data ) int thread_queue_apc( struct process *process, struct thread *thread, struct object *owner, const apc_call_t *call_data )
{ {
struct thread_apc *apc; struct thread_apc *apc;
int ret = 0; int ret = 0;
if ((apc = create_apc( owner, call_data ))) if ((apc = create_apc( owner, call_data )))
{ {
ret = queue_apc( NULL, thread, apc ); ret = queue_apc( process, thread, apc );
release_object( apc ); release_object( apc );
} }
return ret; return ret;
......
...@@ -120,7 +120,7 @@ extern void remove_queue( struct object *obj, struct wait_queue_entry *entry ); ...@@ -120,7 +120,7 @@ extern void remove_queue( struct object *obj, struct wait_queue_entry *entry );
extern void kill_thread( struct thread *thread, int violent_death ); extern void kill_thread( struct thread *thread, int violent_death );
extern void break_thread( struct thread *thread ); extern void break_thread( struct thread *thread );
extern void wake_up( struct object *obj, int max ); extern void wake_up( struct object *obj, int max );
extern int thread_queue_apc( struct thread *thread, struct object *owner, const apc_call_t *call_data ); extern int thread_queue_apc( struct process *process, struct thread *thread, struct object *owner, const apc_call_t *call_data );
extern void thread_cancel_apc( struct thread *thread, struct object *owner, enum apc_type type ); extern void thread_cancel_apc( struct thread *thread, struct object *owner, enum apc_type type );
extern int thread_add_inflight_fd( struct thread *thread, int client, int server ); extern int thread_add_inflight_fd( struct thread *thread, int client, int server );
extern int thread_get_inflight_fd( struct thread *thread, int client ); extern int thread_get_inflight_fd( struct thread *thread, int client );
......
...@@ -122,7 +122,7 @@ static void timer_callback( void *private ) ...@@ -122,7 +122,7 @@ static void timer_callback( void *private )
} }
else data.type = APC_NONE; /* wake up only */ else data.type = APC_NONE; /* wake up only */
if (!thread_queue_apc( timer->thread, &timer->obj, &data )) if (!thread_queue_apc( NULL, timer->thread, &timer->obj, &data ))
{ {
release_object( timer->thread ); release_object( timer->thread );
timer->thread = NULL; timer->thread = NULL;
......
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