server: Make it possible to deliver an APC to any thread alive in the process.
Signed-off-by: Dmitry Timoshkov <dmitry@baikal.ru> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
5350eea78d
commit
288814a4d8
|
@ -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
|
||||||
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
|
||||||
{
|
{
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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 );
|
||||||
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 )
|
||||||
}
|
}
|
||||||
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;
|
||||||
|
|
Loading…
Reference in New Issue