Commit 49b49c30 authored by Alexandre Julliard's avatar Alexandre Julliard

server: Notify the server that an APC has completed in the next get_apc call.

parent 2606ad53
...@@ -659,6 +659,8 @@ static int wait_reply( void *cookie ) ...@@ -659,6 +659,8 @@ static int wait_reply( void *cookie )
*/ */
static void call_apcs( BOOL alertable ) static void call_apcs( BOOL alertable )
{ {
NTSTATUS ret;
HANDLE handle = 0;
FARPROC proc; FARPROC proc;
LARGE_INTEGER time; LARGE_INTEGER time;
void *arg1, *arg2, *arg3; void *arg1, *arg2, *arg3;
...@@ -669,18 +671,23 @@ static void call_apcs( BOOL alertable ) ...@@ -669,18 +671,23 @@ static void call_apcs( BOOL alertable )
SERVER_START_REQ( get_apc ) SERVER_START_REQ( get_apc )
{ {
req->alertable = alertable; req->alertable = alertable;
if (!wine_server_call( req )) type = reply->type; req->prev = handle;
if (!(ret = wine_server_call( req )))
{
handle = reply->handle;
type = reply->type;
proc = reply->func; proc = reply->func;
arg1 = reply->arg1; arg1 = reply->arg1;
arg2 = reply->arg2; arg2 = reply->arg2;
arg3 = reply->arg3; arg3 = reply->arg3;
} }
}
SERVER_END_REQ; SERVER_END_REQ;
if (ret) return; /* no more APCs */
switch (type) switch (type)
{ {
case APC_NONE:
return; /* no more APCs */
case APC_USER: case APC_USER:
proc( arg1, arg2, arg3 ); proc( arg1, arg2, arg3 );
break; break;
......
...@@ -529,10 +529,12 @@ struct get_apc_request ...@@ -529,10 +529,12 @@ struct get_apc_request
{ {
struct request_header __header; struct request_header __header;
int alertable; int alertable;
obj_handle_t prev;
}; };
struct get_apc_reply struct get_apc_reply
{ {
struct reply_header __header; struct reply_header __header;
obj_handle_t handle;
void* func; void* func;
int type; int type;
void* arg1; void* arg1;
...@@ -4415,6 +4417,6 @@ union generic_reply ...@@ -4415,6 +4417,6 @@ union generic_reply
struct query_symlink_reply query_symlink_reply; struct query_symlink_reply query_symlink_reply;
}; };
#define SERVER_PROTOCOL_VERSION 261 #define SERVER_PROTOCOL_VERSION 262
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
...@@ -447,7 +447,9 @@ struct token_groups ...@@ -447,7 +447,9 @@ struct token_groups
/* Get next APC to call */ /* Get next APC to call */
@REQ(get_apc) @REQ(get_apc)
int alertable; /* is thread alertable? */ int alertable; /* is thread alertable? */
obj_handle_t prev; /* handle to previous APC */
@REPLY @REPLY
obj_handle_t handle; /* handle to APC */
void* func; /* function to call */ void* func; /* function to call */
int type; /* function type */ int type; /* function type */
void* arg1; /* function arguments */ void* arg1; /* function arguments */
......
...@@ -71,6 +71,7 @@ struct thread_apc ...@@ -71,6 +71,7 @@ struct thread_apc
struct object obj; /* object header */ struct object obj; /* object header */
struct list entry; /* queue linked list */ struct list entry; /* queue linked list */
struct object *owner; /* object that queued this apc */ struct object *owner; /* object that queued this apc */
int executed; /* has it been executed by the client? */
void *func; /* function to call in client */ void *func; /* function to call in client */
enum apc_type type; /* type of apc function */ enum apc_type type; /* type of apc function */
void *arg1; /* function arguments */ void *arg1; /* function arguments */
...@@ -310,7 +311,8 @@ static void dump_thread_apc( struct object *obj, int verbose ) ...@@ -310,7 +311,8 @@ static void dump_thread_apc( struct object *obj, int verbose )
static int thread_apc_signaled( struct object *obj, struct thread *thread ) static int thread_apc_signaled( struct object *obj, struct thread *thread )
{ {
return 0; struct thread_apc *apc = (struct thread_apc *)obj;
return apc->executed;
} }
/* get a thread pointer from a thread id (and increment the refcount) */ /* get a thread pointer from a thread id (and increment the refcount) */
...@@ -679,6 +681,7 @@ int thread_queue_apc( struct thread *thread, struct object *owner, void *func, ...@@ -679,6 +681,7 @@ int thread_queue_apc( struct thread *thread, struct object *owner, void *func,
apc->arg1 = arg1; apc->arg1 = arg1;
apc->arg2 = arg2; apc->arg2 = arg2;
apc->arg3 = arg3; apc->arg3 = arg3;
apc->executed = 0;
list_add_tail( queue, &apc->entry ); list_add_tail( queue, &apc->entry );
if (!list_prev( queue, &apc->entry )) /* first one */ if (!list_prev( queue, &apc->entry )) /* first one */
wake_thread( thread ); wake_thread( thread );
...@@ -1061,13 +1064,22 @@ DECL_HANDLER(get_apc) ...@@ -1061,13 +1064,22 @@ DECL_HANDLER(get_apc)
{ {
struct thread_apc *apc; struct thread_apc *apc;
if (req->prev)
{
if (!(apc = (struct thread_apc *)get_handle_obj( current->process, req->prev,
0, &thread_apc_ops ))) return;
apc->executed = 1;
wake_up( &apc->obj, 0 );
close_handle( current->process, req->prev );
release_object( apc );
}
for (;;) for (;;)
{ {
if (!(apc = thread_dequeue_apc( current, !req->alertable ))) if (!(apc = thread_dequeue_apc( current, !req->alertable )))
{ {
/* no more APCs */ /* no more APCs */
reply->func = NULL; set_error( STATUS_PENDING );
reply->type = APC_NONE;
return; return;
} }
/* Optimization: ignore APCs that have a NULL func; they are only used /* Optimization: ignore APCs that have a NULL func; they are only used
...@@ -1077,11 +1089,15 @@ DECL_HANDLER(get_apc) ...@@ -1077,11 +1089,15 @@ DECL_HANDLER(get_apc)
if (apc->func || apc->type == APC_ASYNC_IO) break; if (apc->func || apc->type == APC_ASYNC_IO) break;
release_object( apc ); release_object( apc );
} }
if ((reply->handle = alloc_handle( current->process, apc, SYNCHRONIZE, 0 )))
{
reply->func = apc->func; reply->func = apc->func;
reply->type = apc->type; reply->type = apc->type;
reply->arg1 = apc->arg1; reply->arg1 = apc->arg1;
reply->arg2 = apc->arg2; reply->arg2 = apc->arg2;
reply->arg3 = apc->arg3; reply->arg3 = apc->arg3;
}
release_object( apc ); release_object( apc );
} }
......
...@@ -854,11 +854,13 @@ static void dump_queue_apc_request( const struct queue_apc_request *req ) ...@@ -854,11 +854,13 @@ static void dump_queue_apc_request( const struct queue_apc_request *req )
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 ); fprintf( stderr, " alertable=%d,", req->alertable );
fprintf( stderr, " prev=%p", req->prev );
} }
static void dump_get_apc_reply( const struct get_apc_reply *req ) static void dump_get_apc_reply( const struct get_apc_reply *req )
{ {
fprintf( stderr, " handle=%p,", req->handle );
fprintf( stderr, " func=%p,", req->func ); fprintf( stderr, " func=%p,", req->func );
fprintf( stderr, " type=%d,", req->type ); fprintf( stderr, " type=%d,", req->type );
fprintf( stderr, " arg1=%p,", req->arg1 ); fprintf( stderr, " arg1=%p,", req->arg1 );
......
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