Commit 2362380b authored by Alexandre Julliard's avatar Alexandre Julliard

Added separate queue for "system" APCs that get called even when the

thread is not in an alertable state. Specify the select_request timeout as absolute value so that we can restart the request when interrupted.
parent d3f2581d
...@@ -340,6 +340,7 @@ struct queue_apc_request ...@@ -340,6 +340,7 @@ struct queue_apc_request
{ {
REQUEST_HEADER; /* request header */ REQUEST_HEADER; /* request header */
IN handle_t handle; /* thread handle */ IN handle_t handle; /* thread handle */
IN int user; /* user or system apc? */
IN void* func; /* function to call */ IN void* func; /* function to call */
IN void* param; /* param for function to call */ IN void* param; /* param for function to call */
}; };
...@@ -349,6 +350,7 @@ struct queue_apc_request ...@@ -349,6 +350,7 @@ struct queue_apc_request
struct get_apc_request struct get_apc_request
{ {
REQUEST_HEADER; /* request header */ REQUEST_HEADER; /* request header */
IN int alertable; /* is thread alertable? */
OUT void* func; /* function to call */ OUT void* func; /* function to call */
OUT int type; /* function type */ OUT int type; /* function type */
OUT VARARG(args,ptrs); /* function arguments */ OUT VARARG(args,ptrs); /* function arguments */
...@@ -412,13 +414,15 @@ struct select_request ...@@ -412,13 +414,15 @@ struct select_request
{ {
REQUEST_HEADER; /* request header */ REQUEST_HEADER; /* request header */
IN int flags; /* wait flags (see below) */ IN int flags; /* wait flags (see below) */
IN int timeout; /* timeout in ms */ IN int sec; /* absolute timeout */
IN int usec; /* absolute timeout */
OUT int signaled; /* signaled handle */ OUT int signaled; /* signaled handle */
IN VARARG(handles,handles); /* handles to select on */ IN VARARG(handles,handles); /* handles to select on */
}; };
#define SELECT_ALL 1 #define SELECT_ALL 1
#define SELECT_ALERTABLE 2 #define SELECT_ALERTABLE 2
#define SELECT_TIMEOUT 4 #define SELECT_INTERRUPTIBLE 4
#define SELECT_TIMEOUT 8
/* Create an event */ /* Create an event */
...@@ -1576,7 +1580,7 @@ union generic_request ...@@ -1576,7 +1580,7 @@ union generic_request
struct async_result_request async_result; struct async_result_request async_result;
}; };
#define SERVER_PROTOCOL_VERSION 33 #define SERVER_PROTOCOL_VERSION 34
/* ### make_requests end ### */ /* ### make_requests end ### */
/* Everything above this line is generated automatically by tools/make_requests */ /* Everything above this line is generated automatically by tools/make_requests */
......
...@@ -16,11 +16,30 @@ ...@@ -16,11 +16,30 @@
/*********************************************************************** /***********************************************************************
* get_timeout
*/
inline static void get_timeout( struct timeval *when, int timeout )
{
gettimeofday( when, 0 );
if (timeout)
{
long sec = timeout / 1000;
if ((when->tv_usec += (timeout - 1000*sec) * 1000) >= 1000000)
{
when->tv_usec -= 1000000;
when->tv_sec++;
}
when->tv_sec += sec;
}
}
/***********************************************************************
* call_apcs * call_apcs
* *
* Call outstanding APCs. * Call outstanding APCs.
*/ */
static void call_apcs(void) static void call_apcs( BOOL alertable )
{ {
FARPROC proc = NULL; FARPROC proc = NULL;
FILETIME ft; FILETIME ft;
...@@ -32,6 +51,7 @@ static void call_apcs(void) ...@@ -32,6 +51,7 @@ static void call_apcs(void)
SERVER_START_REQ SERVER_START_REQ
{ {
struct get_apc_request *req = server_alloc_req( sizeof(*req), sizeof(args) ); struct get_apc_request *req = server_alloc_req( sizeof(*req), sizeof(args) );
req->alertable = alertable;
if (!server_call( REQ_GET_APC )) if (!server_call( REQ_GET_APC ))
{ {
type = req->type; type = req->type;
...@@ -119,6 +139,7 @@ DWORD WINAPI WaitForMultipleObjectsEx( DWORD count, const HANDLE *handles, ...@@ -119,6 +139,7 @@ DWORD WINAPI WaitForMultipleObjectsEx( DWORD count, const HANDLE *handles,
BOOL alertable ) BOOL alertable )
{ {
int i, ret; int i, ret;
struct timeval tv;
if (count > MAXIMUM_WAIT_OBJECTS) if (count > MAXIMUM_WAIT_OBJECTS)
{ {
...@@ -126,24 +147,33 @@ DWORD WINAPI WaitForMultipleObjectsEx( DWORD count, const HANDLE *handles, ...@@ -126,24 +147,33 @@ DWORD WINAPI WaitForMultipleObjectsEx( DWORD count, const HANDLE *handles,
return WAIT_FAILED; return WAIT_FAILED;
} }
SERVER_START_REQ if (timeout == INFINITE) tv.tv_sec = tv.tv_usec = 0;
else get_timeout( &tv, timeout );
for (;;)
{ {
struct select_request *req = server_alloc_req( sizeof(*req), count * sizeof(int) ); SERVER_START_REQ
int *data = server_data_ptr( req ); {
struct select_request *req = server_alloc_req( sizeof(*req), count * sizeof(int) );
int *data = server_data_ptr( req );
req->flags = 0; req->flags = SELECT_INTERRUPTIBLE;
req->timeout = timeout; req->sec = tv.tv_sec;
for (i = 0; i < count; i++) data[i] = handles[i]; req->usec = tv.tv_usec;
for (i = 0; i < count; i++) data[i] = handles[i];
if (wait_all) req->flags |= SELECT_ALL; if (wait_all) req->flags |= SELECT_ALL;
if (alertable) req->flags |= SELECT_ALERTABLE; if (alertable) req->flags |= SELECT_ALERTABLE;
if (timeout != INFINITE) req->flags |= SELECT_TIMEOUT; if (timeout != INFINITE) req->flags |= SELECT_TIMEOUT;
server_call( REQ_SELECT ); server_call( REQ_SELECT );
ret = req->signaled; ret = req->signaled;
}
SERVER_END_REQ;
if (ret != STATUS_USER_APC) break;
call_apcs( alertable );
if (alertable) break;
} }
SERVER_END_REQ;
if (ret == STATUS_USER_APC) call_apcs();
return ret; return ret;
} }
......
...@@ -638,6 +638,7 @@ DWORD WINAPI QueueUserAPC( PAPCFUNC func, HANDLE hthread, ULONG_PTR data ) ...@@ -638,6 +638,7 @@ DWORD WINAPI QueueUserAPC( PAPCFUNC func, HANDLE hthread, ULONG_PTR data )
{ {
struct queue_apc_request *req = server_alloc_req( sizeof(*req), 0 ); struct queue_apc_request *req = server_alloc_req( sizeof(*req), 0 );
req->handle = hthread; req->handle = hthread;
req->user = 1;
req->func = func; req->func = func;
req->param = (void *)data; req->param = (void *)data;
ret = !server_call( REQ_QUEUE_APC ); ret = !server_call( REQ_QUEUE_APC );
......
...@@ -213,25 +213,25 @@ DECL_HANDLER(create_async) ...@@ -213,25 +213,25 @@ DECL_HANDLER(create_async)
static void async_poll_event( struct object *obj, int event ) static void async_poll_event( struct object *obj, int event )
{ {
struct async *ov = (struct async *) obj; struct async *ov = (struct async *) obj;
/* queue an APC in the client thread to do our dirty work */ /* queue an APC in the client thread to do our dirty work */
ov->obj.ops->remove_queue(&ov->obj,&ov->wait); ov->obj.ops->remove_queue(&ov->obj,&ov->wait);
/* FIXME: this should be a function pointer */ /* FIXME: this should be a function pointer */
event = serial_async_poll_event(obj,event); event = serial_async_poll_event(obj,event);
thread_queue_apc(ov->thread, NULL, ov->func, APC_ASYNC, 3, thread_queue_apc(ov->thread, NULL, ov->func, APC_ASYNC, 1, 3,
ov->client_overlapped, ov->buffer, event); ov->client_overlapped, ov->buffer, event);
} }
/* handler for async i/o timeouts */ /* handler for async i/o timeouts */
static void overlapped_timeout (void *private) static void overlapped_timeout (void *private)
{ {
struct async *ov = (struct async *) private; struct async *ov = (struct async *) private;
ov->obj.ops->remove_queue(&ov->obj,&ov->wait); ov->obj.ops->remove_queue(&ov->obj,&ov->wait);
thread_queue_apc(ov->thread, NULL, ov->func, APC_ASYNC, 3, thread_queue_apc(ov->thread, NULL, ov->func, APC_ASYNC, 1, 3,
ov->client_overlapped,ov->buffer, 0); ov->client_overlapped,ov->buffer, 0);
} }
......
...@@ -363,14 +363,21 @@ static int wait_for_debug_event( int timeout ) ...@@ -363,14 +363,21 @@ static int wait_for_debug_event( int timeout )
struct debug_ctx *debug_ctx = current->debug_ctx; struct debug_ctx *debug_ctx = current->debug_ctx;
struct object *obj = &debug_ctx->obj; struct object *obj = &debug_ctx->obj;
int flags = 0; int flags = 0;
struct timeval tv;
if (!debug_ctx) /* current thread is not a debugger */ if (!debug_ctx) /* current thread is not a debugger */
{ {
set_error( STATUS_INVALID_HANDLE ); set_error( STATUS_INVALID_HANDLE );
return 0; return 0;
} }
if (timeout != -1) flags = SELECT_TIMEOUT; if (timeout != -1)
return sleep_on( 1, &obj, flags, timeout, build_wait_debug_reply ); {
flags = SELECT_TIMEOUT;
gettimeofday( &tv, 0 );
add_timeout( &tv, timeout );
}
else tv.tv_sec = tv.tv_usec = 0;
return sleep_on( 1, &obj, flags, tv.tv_sec, tv.tv_usec, build_wait_debug_reply );
} }
/* continue a debug event */ /* continue a debug event */
...@@ -603,7 +610,7 @@ DECL_HANDLER(exception_event) ...@@ -603,7 +610,7 @@ DECL_HANDLER(exception_event)
{ {
struct object *obj = &event->obj; struct object *obj = &event->obj;
current->context = context; current->context = context;
sleep_on( 1, &obj, 0, -1, build_exception_event_reply ); sleep_on( 1, &obj, 0, 0, 0, build_exception_event_reply );
release_object( event ); release_object( event );
} }
} }
......
...@@ -771,8 +771,12 @@ DECL_HANDLER(wait_process) ...@@ -771,8 +771,12 @@ DECL_HANDLER(wait_process)
} }
else else
{ {
struct timeval timeout;
struct object *obj = &current->info->obj; struct object *obj = &current->info->obj;
sleep_on( 1, &obj, SELECT_TIMEOUT, req->timeout, build_wait_process_reply ); gettimeofday( &timeout, 0 );
add_timeout( &timeout, req->timeout );
sleep_on( 1, &obj, SELECT_TIMEOUT, timeout.tv_sec, timeout.tv_usec,
build_wait_process_reply );
} }
} }
......
...@@ -64,7 +64,7 @@ static void dump_thread( struct object *obj, int verbose ); ...@@ -64,7 +64,7 @@ static void dump_thread( struct object *obj, int verbose );
static int thread_signaled( struct object *obj, struct thread *thread ); static int thread_signaled( struct object *obj, struct thread *thread );
extern void thread_poll_event( struct object *obj, int event ); extern void thread_poll_event( struct object *obj, int event );
static void destroy_thread( struct object *obj ); static void destroy_thread( struct object *obj );
static struct thread_apc *thread_dequeue_apc( struct thread *thread ); static struct thread_apc *thread_dequeue_apc( struct thread *thread, int system_only );
static const struct object_ops thread_ops = static const struct object_ops thread_ops =
{ {
...@@ -147,8 +147,10 @@ struct thread *create_thread( int fd, struct process *process ) ...@@ -147,8 +147,10 @@ struct thread *create_thread( int fd, struct process *process )
thread->queue = NULL; thread->queue = NULL;
thread->info = NULL; thread->info = NULL;
thread->wait = NULL; thread->wait = NULL;
thread->apc_head = NULL; thread->system_apc.head = NULL;
thread->apc_tail = NULL; thread->system_apc.tail = NULL;
thread->user_apc.head = NULL;
thread->user_apc.tail = NULL;
thread->error = 0; thread->error = 0;
thread->pass_fd = -1; thread->pass_fd = -1;
thread->request_fd = NULL; thread->request_fd = NULL;
...@@ -211,7 +213,7 @@ static void destroy_thread( struct object *obj ) ...@@ -211,7 +213,7 @@ static void destroy_thread( struct object *obj )
if (thread->next) thread->next->prev = thread->prev; if (thread->next) thread->next->prev = thread->prev;
if (thread->prev) thread->prev->next = thread->next; if (thread->prev) thread->prev->next = thread->next;
else first_thread = thread->next; else first_thread = thread->next;
while ((apc = thread_dequeue_apc( thread ))) free( apc ); while ((apc = thread_dequeue_apc( thread, 0 ))) free( apc );
if (thread->info) release_object( thread->info ); if (thread->info) release_object( thread->info );
if (thread->queue) release_object( thread->queue ); if (thread->queue) release_object( thread->queue );
if (thread->buffer != (void *)-1) munmap( thread->buffer, MAX_REQUEST_LENGTH ); if (thread->buffer != (void *)-1) munmap( thread->buffer, MAX_REQUEST_LENGTH );
...@@ -354,7 +356,7 @@ static void end_wait( struct thread *thread ) ...@@ -354,7 +356,7 @@ static void end_wait( struct thread *thread )
/* build the thread wait structure */ /* build the thread wait structure */
static int wait_on( int count, struct object *objects[], int flags, static int wait_on( int count, struct object *objects[], int flags,
int timeout, sleep_reply func ) int sec, int usec, sleep_reply func )
{ {
struct thread_wait *wait; struct thread_wait *wait;
struct wait_queue_entry *entry; struct wait_queue_entry *entry;
...@@ -368,8 +370,8 @@ static int wait_on( int count, struct object *objects[], int flags, ...@@ -368,8 +370,8 @@ static int wait_on( int count, struct object *objects[], int flags,
wait->reply = func; wait->reply = func;
if (flags & SELECT_TIMEOUT) if (flags & SELECT_TIMEOUT)
{ {
gettimeofday( &wait->timeout, 0 ); wait->timeout.tv_sec = sec;
add_timeout( &wait->timeout, timeout ); wait->timeout.tv_usec = usec;
} }
for (i = 0, entry = wait->queues; i < count; i++, entry++) for (i = 0, entry = wait->queues; i < count; i++, entry++)
...@@ -425,7 +427,8 @@ static int check_wait( struct thread *thread, struct object **object ) ...@@ -425,7 +427,8 @@ static int check_wait( struct thread *thread, struct object **object )
} }
other_checks: other_checks:
if ((wait->flags & SELECT_ALERTABLE) && thread->apc_head) return STATUS_USER_APC; if ((wait->flags & SELECT_INTERRUPTIBLE) && thread->system_apc.head) return STATUS_USER_APC;
if ((wait->flags & SELECT_ALERTABLE) && thread->user_apc.head) return STATUS_USER_APC;
if (wait->flags & SELECT_TIMEOUT) if (wait->flags & SELECT_TIMEOUT)
{ {
struct timeval now; struct timeval now;
...@@ -469,10 +472,10 @@ static void thread_timeout( void *ptr ) ...@@ -469,10 +472,10 @@ static void thread_timeout( void *ptr )
} }
/* sleep on a list of objects */ /* sleep on a list of objects */
int sleep_on( int count, struct object *objects[], int flags, int timeout, sleep_reply func ) int sleep_on( int count, struct object *objects[], int flags, int sec, int usec, sleep_reply func )
{ {
assert( !current->wait ); assert( !current->wait );
if (!wait_on( count, objects, flags, timeout, func )) return 0; if (!wait_on( count, objects, flags, sec, usec, func )) return 0;
if (wake_thread( current )) return 1; if (wake_thread( current )) return 1;
/* now we need to wait */ /* now we need to wait */
if (flags & SELECT_TIMEOUT) if (flags & SELECT_TIMEOUT)
...@@ -488,7 +491,7 @@ int sleep_on( int count, struct object *objects[], int flags, int timeout, sleep ...@@ -488,7 +491,7 @@ int sleep_on( int count, struct object *objects[], int flags, int timeout, sleep
} }
/* select on a list of handles */ /* select on a list of handles */
static int select_on( int count, handle_t *handles, int flags, int timeout ) static int select_on( int count, handle_t *handles, int flags, int sec, int usec )
{ {
int ret = 0; int ret = 0;
int i; int i;
...@@ -504,7 +507,7 @@ static int select_on( int count, handle_t *handles, int flags, int timeout ) ...@@ -504,7 +507,7 @@ static int select_on( int count, handle_t *handles, int flags, int timeout )
if (!(objects[i] = get_handle_obj( current->process, handles[i], SYNCHRONIZE, NULL ))) if (!(objects[i] = get_handle_obj( current->process, handles[i], SYNCHRONIZE, NULL )))
break; break;
} }
if (i == count) ret = sleep_on( count, objects, flags, timeout, build_select_reply ); if (i == count) ret = sleep_on( count, objects, flags, sec, usec, build_select_reply );
while (--i >= 0) release_object( objects[i] ); while (--i >= 0) release_object( objects[i] );
return ret; return ret;
} }
...@@ -528,15 +531,16 @@ void wake_up( struct object *obj, int max ) ...@@ -528,15 +531,16 @@ void wake_up( struct object *obj, int max )
/* queue an async procedure call */ /* queue an async procedure call */
int thread_queue_apc( struct thread *thread, struct object *owner, void *func, int thread_queue_apc( struct thread *thread, struct object *owner, void *func,
enum apc_type type, int nb_args, ... ) enum apc_type type, int system, int nb_args, ... )
{ {
struct thread_apc *apc; struct thread_apc *apc;
struct apc_queue *queue = system ? &thread->system_apc : &thread->user_apc;
/* cancel a possible previous APC with the same owner */ /* cancel a possible previous APC with the same owner */
if (owner) thread_cancel_apc( thread, owner ); if (owner) thread_cancel_apc( thread, owner, system );
if (!(apc = mem_alloc( sizeof(*apc) + (nb_args-1)*sizeof(apc->args[0]) ))) return 0; if (!(apc = mem_alloc( sizeof(*apc) + (nb_args-1)*sizeof(apc->args[0]) ))) return 0;
apc->prev = thread->apc_tail; apc->prev = queue->tail;
apc->next = NULL; apc->next = NULL;
apc->owner = owner; apc->owner = owner;
apc->func = func; apc->func = func;
...@@ -550,40 +554,44 @@ int thread_queue_apc( struct thread *thread, struct object *owner, void *func, ...@@ -550,40 +554,44 @@ int thread_queue_apc( struct thread *thread, struct object *owner, void *func,
for (i = 0; i < nb_args; i++) apc->args[i] = va_arg( args, void * ); for (i = 0; i < nb_args; i++) apc->args[i] = va_arg( args, void * );
va_end( args ); va_end( args );
} }
thread->apc_tail = apc; queue->tail = apc;
if (!apc->prev) /* first one */ if (!apc->prev) /* first one */
{ {
thread->apc_head = apc; queue->head = apc;
if (thread->wait && wake_thread( thread )) send_reply( thread ); if (thread->wait && wake_thread( thread )) send_reply( thread );
} }
return 1; return 1;
} }
/* cancel the async procedure call owned by a specific object */ /* cancel the async procedure call owned by a specific object */
void thread_cancel_apc( struct thread *thread, struct object *owner ) void thread_cancel_apc( struct thread *thread, struct object *owner, int system )
{ {
struct thread_apc *apc; struct thread_apc *apc;
for (apc = thread->apc_head; apc; apc = apc->next) struct apc_queue *queue = system ? &thread->system_apc : &thread->user_apc;
for (apc = queue->head; apc; apc = apc->next)
{ {
if (apc->owner != owner) continue; if (apc->owner != owner) continue;
if (apc->next) apc->next->prev = apc->prev; if (apc->next) apc->next->prev = apc->prev;
else thread->apc_tail = apc->prev; else queue->tail = apc->prev;
if (apc->prev) apc->prev->next = apc->next; if (apc->prev) apc->prev->next = apc->next;
else thread->apc_head = apc->next; else queue->head = apc->next;
free( apc ); free( apc );
return; return;
} }
} }
/* remove the head apc from the queue; the returned pointer must be freed by the caller */ /* remove the head apc from the queue; the returned pointer must be freed by the caller */
static struct thread_apc *thread_dequeue_apc( struct thread *thread ) static struct thread_apc *thread_dequeue_apc( struct thread *thread, int system_only )
{ {
struct thread_apc *apc = thread->apc_head; struct thread_apc *apc;
if (apc) struct apc_queue *queue = &thread->system_apc;
if (!queue->head && !system_only) queue = &thread->user_apc;
if ((apc = queue->head))
{ {
if (apc->next) apc->next->prev = NULL; if (apc->next) apc->next->prev = NULL;
else thread->apc_tail = NULL; else queue->tail = NULL;
thread->apc_head = apc->next; queue->head = apc->next;
} }
return apc; return apc;
} }
...@@ -811,7 +819,7 @@ DECL_HANDLER(resume_thread) ...@@ -811,7 +819,7 @@ DECL_HANDLER(resume_thread)
DECL_HANDLER(select) DECL_HANDLER(select)
{ {
int count = get_req_data_size(req) / sizeof(int); int count = get_req_data_size(req) / sizeof(int);
if (!select_on( count, get_req_data(req), req->flags, req->timeout )) if (!select_on( count, get_req_data(req), req->flags, req->sec, req->usec ))
req->signaled = -1; req->signaled = -1;
} }
...@@ -821,7 +829,7 @@ DECL_HANDLER(queue_apc) ...@@ -821,7 +829,7 @@ DECL_HANDLER(queue_apc)
struct thread *thread; struct thread *thread;
if ((thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT ))) if ((thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT )))
{ {
thread_queue_apc( thread, NULL, req->func, APC_USER, 1, req->param ); thread_queue_apc( thread, NULL, req->func, APC_USER, !req->user, 1, req->param );
release_object( thread ); release_object( thread );
} }
} }
...@@ -834,7 +842,7 @@ DECL_HANDLER(get_apc) ...@@ -834,7 +842,7 @@ DECL_HANDLER(get_apc)
for (;;) for (;;)
{ {
if (!(apc = thread_dequeue_apc( current ))) if (!(apc = thread_dequeue_apc( current, !req->alertable )))
{ {
/* no more APCs */ /* no more APCs */
req->func = NULL; req->func = NULL;
......
...@@ -30,6 +30,11 @@ enum run_state ...@@ -30,6 +30,11 @@ enum run_state
TERMINATED /* terminated */ TERMINATED /* terminated */
}; };
struct apc_queue
{
struct thread_apc *head;
struct thread_apc *tail;
};
struct thread struct thread
{ {
...@@ -45,8 +50,8 @@ struct thread ...@@ -45,8 +50,8 @@ struct thread
struct msg_queue *queue; /* message queue */ struct msg_queue *queue; /* message queue */
struct startup_info*info; /* startup info for child process */ struct startup_info*info; /* startup info for child process */
struct thread_wait *wait; /* current wait condition if sleeping */ struct thread_wait *wait; /* current wait condition if sleeping */
struct thread_apc *apc_head; /* queue of async procedure calls */ struct apc_queue system_apc; /* queue of system async procedure calls */
struct thread_apc *apc_tail; /* queue of async procedure calls */ struct apc_queue user_apc; /* queue of user async procedure calls */
unsigned int error; /* current error code */ unsigned int error; /* current error code */
struct object *request_fd; /* fd for receiving client requests */ struct object *request_fd; /* fd for receiving client requests */
int pass_fd; /* fd to pass to the client */ int pass_fd; /* fd to pass to the client */
...@@ -92,10 +97,10 @@ extern void remove_queue( struct object *obj, struct wait_queue_entry *entry ); ...@@ -92,10 +97,10 @@ 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 wake_up( struct object *obj, int max ); extern void wake_up( struct object *obj, int max );
extern int sleep_on( int count, struct object *objects[], int flags, extern int sleep_on( int count, struct object *objects[], int flags,
int timeout, sleep_reply func ); int sec, int usec, sleep_reply func );
extern int thread_queue_apc( struct thread *thread, struct object *owner, void *func, extern int thread_queue_apc( struct thread *thread, struct object *owner, void *func,
enum apc_type type, int nb_args, ... ); enum apc_type type, int system, int nb_args, ... );
extern void thread_cancel_apc( struct thread *thread, struct object *owner ); extern void thread_cancel_apc( struct thread *thread, struct object *owner, int system );
extern struct thread_snapshot *thread_snap( int *count ); extern struct thread_snapshot *thread_snap( int *count );
/* ptrace functions */ /* ptrace functions */
......
...@@ -78,7 +78,7 @@ static void timer_callback( void *private ) ...@@ -78,7 +78,7 @@ static void timer_callback( void *private )
/* queue an APC */ /* queue an APC */
if (timer->thread) if (timer->thread)
thread_queue_apc( timer->thread, &timer->obj, timer->callback, APC_TIMER, 3, thread_queue_apc( timer->thread, &timer->obj, timer->callback, APC_TIMER, 0, 3,
(void *)timer->when.tv_sec, (void *)timer->when.tv_usec, timer->arg ); (void *)timer->when.tv_sec, (void *)timer->when.tv_usec, timer->arg );
if (timer->period) /* schedule the next expiration */ if (timer->period) /* schedule the next expiration */
...@@ -103,7 +103,7 @@ static void cancel_timer( struct timer *timer ) ...@@ -103,7 +103,7 @@ static void cancel_timer( struct timer *timer )
} }
if (timer->thread) if (timer->thread)
{ {
thread_cancel_apc( timer->thread, &timer->obj ); thread_cancel_apc( timer->thread, &timer->obj, 0 );
timer->thread = NULL; timer->thread = NULL;
} }
} }
......
...@@ -466,12 +466,14 @@ static void dump_unload_dll_request( const struct unload_dll_request *req ) ...@@ -466,12 +466,14 @@ static void dump_unload_dll_request( const struct unload_dll_request *req )
static void dump_queue_apc_request( const struct queue_apc_request *req ) static void dump_queue_apc_request( const struct queue_apc_request *req )
{ {
fprintf( stderr, " handle=%d,", req->handle ); fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " user=%d,", req->user );
fprintf( stderr, " func=%p,", req->func ); fprintf( stderr, " func=%p,", req->func );
fprintf( stderr, " param=%p", req->param ); fprintf( stderr, " param=%p", req->param );
} }
static void dump_get_apc_request( const struct get_apc_request *req ) static void dump_get_apc_request( const struct get_apc_request *req )
{ {
fprintf( stderr, " alertable=%d", req->alertable );
} }
static void dump_get_apc_reply( const struct get_apc_request *req ) static void dump_get_apc_reply( const struct get_apc_request *req )
...@@ -537,7 +539,8 @@ static void dump_open_process_reply( const struct open_process_request *req ) ...@@ -537,7 +539,8 @@ static void dump_open_process_reply( const struct open_process_request *req )
static void dump_select_request( const struct select_request *req ) static void dump_select_request( const struct select_request *req )
{ {
fprintf( stderr, " flags=%d,", req->flags ); fprintf( stderr, " flags=%d,", req->flags );
fprintf( stderr, " timeout=%d,", req->timeout ); fprintf( stderr, " sec=%d,", req->sec );
fprintf( stderr, " usec=%d,", req->usec );
fprintf( stderr, " handles=" ); fprintf( stderr, " handles=" );
cur_pos += dump_varargs_handles( req ); cur_pos += dump_varargs_handles( req );
} }
......
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