Implemented NtQueueApcThread, and changed the server APC interface to
always take 3 parameters.
Implemented a number of other ntdll thread functions, and use them
from the kernel ones.
diff --git a/server/async.c b/server/async.c
index 039833e..338f0d1 100644
--- a/server/async.c
+++ b/server/async.c
@@ -65,7 +65,8 @@
{
/* fprintf(stderr,"notifying %p!\n",async->overlapped); */
async->status = status;
- thread_queue_apc(async->thread, NULL, NULL, APC_ASYNC_IO, 1, 2, async->overlapped, status);
+ thread_queue_apc(async->thread, NULL, NULL, APC_ASYNC_IO, 1,
+ async->overlapped, (void *)status, NULL );
}
void destroy_async_queue( struct async_queue *q )
diff --git a/server/named_pipe.c b/server/named_pipe.c
index 05cdda7..984c575 100644
--- a/server/named_pipe.c
+++ b/server/named_pipe.c
@@ -151,8 +151,8 @@
if(user->thread && user->func && user->overlapped)
{
/* queue a system APC, to notify a waiting thread */
- thread_queue_apc(user->thread,NULL,user->func,
- APC_ASYNC,1,2,user->overlapped,status);
+ thread_queue_apc(user->thread, NULL, user->func, APC_ASYNC, 1,
+ user->overlapped, (void *)status, NULL);
}
if (user->thread) release_object(user->thread);
user->thread = NULL;
@@ -426,7 +426,7 @@
/* this should use notify_waiter,
but no pipe_user object exists now... */
thread_queue_apc(current,NULL,req->func,
- APC_ASYNC,1,2,req->overlapped,STATUS_SUCCESS);
+ APC_ASYNC, 1, req->overlapped, STATUS_SUCCESS, NULL);
release_object(partner);
}
else
diff --git a/server/protocol.def b/server/protocol.def
index b27788b..90565f8 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -417,7 +417,9 @@
obj_handle_t handle; /* thread handle */
int user; /* user or system apc? */
void* func; /* function to call */
- void* param; /* param for function to call */
+ void* arg1; /* params for function to call */
+ void* arg2;
+ void* arg3;
@END
@@ -427,7 +429,9 @@
@REPLY
void* func; /* function to call */
int type; /* function type */
- VARARG(args,ptrs); /* function arguments */
+ void* arg1; /* function arguments */
+ void* arg2;
+ void* arg3;
@END
enum apc_type { APC_NONE, APC_USER, APC_TIMER, APC_ASYNC, APC_ASYNC_IO };
diff --git a/server/thread.c b/server/thread.c
index ad310c9..c6ef4ac 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -67,7 +67,9 @@
void *func; /* function to call in client */
enum apc_type type; /* type of apc function */
int nb_args; /* number of arguments */
- void *args[1]; /* function arguments */
+ void *arg1; /* function arguments */
+ void *arg2;
+ void *arg3;
};
@@ -580,7 +582,7 @@
/* queue an async procedure call */
int thread_queue_apc( struct thread *thread, struct object *owner, void *func,
- enum apc_type type, int system, int nb_args, ... )
+ enum apc_type type, int system, void *arg1, void *arg2, void *arg3 )
{
struct thread_apc *apc;
struct apc_queue *queue = system ? &thread->system_apc : &thread->user_apc;
@@ -589,21 +591,15 @@
if (owner) thread_cancel_apc( thread, owner, system );
if (thread->state == TERMINATED) return 0;
- if (!(apc = mem_alloc( sizeof(*apc) + (nb_args-1)*sizeof(apc->args[0]) ))) return 0;
- apc->prev = queue->tail;
- apc->next = NULL;
- apc->owner = owner;
- apc->func = func;
- apc->type = type;
- apc->nb_args = nb_args;
- if (nb_args)
- {
- int i;
- va_list args;
- va_start( args, nb_args );
- for (i = 0; i < nb_args; i++) apc->args[i] = va_arg( args, void * );
- va_end( args );
- }
+ if (!(apc = mem_alloc( sizeof(*apc) ))) return 0;
+ apc->prev = queue->tail;
+ apc->next = NULL;
+ apc->owner = owner;
+ apc->func = func;
+ apc->type = type;
+ apc->arg1 = arg1;
+ apc->arg2 = arg2;
+ apc->arg3 = arg3;
queue->tail = apc;
if (!apc->prev) /* first one */
{
@@ -972,7 +968,8 @@
struct thread *thread;
if ((thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT )))
{
- thread_queue_apc( thread, NULL, req->func, APC_USER, !req->user, 1, req->param );
+ thread_queue_apc( thread, NULL, req->func, APC_USER, !req->user,
+ req->arg1, req->arg2, req->arg3 );
release_object( thread );
}
}
@@ -981,7 +978,6 @@
DECL_HANDLER(get_apc)
{
struct thread_apc *apc;
- size_t size;
for (;;)
{
@@ -999,11 +995,11 @@
if (apc->func || apc->type == APC_ASYNC_IO) break;
free( apc );
}
- size = apc->nb_args * sizeof(apc->args[0]);
- if (size > get_reply_max_size()) size = get_reply_max_size();
reply->func = apc->func;
reply->type = apc->type;
- set_reply_data( apc->args, size );
+ reply->arg1 = apc->arg1;
+ reply->arg2 = apc->arg2;
+ reply->arg3 = apc->arg3;
free( apc );
}
diff --git a/server/thread.h b/server/thread.h
index f30ef4c..b0fa9c3 100644
--- a/server/thread.h
+++ b/server/thread.h
@@ -118,7 +118,7 @@
extern void kill_thread( struct thread *thread, int violent_death );
extern void wake_up( struct object *obj, int max );
extern int thread_queue_apc( struct thread *thread, struct object *owner, void *func,
- enum apc_type type, int system, int nb_args, ... );
+ enum apc_type type, int system, void *arg1, void *arg2, void *arg3 );
extern void thread_cancel_apc( struct thread *thread, struct object *owner, int system );
extern int thread_add_inflight_fd( struct thread *thread, int client, int server );
extern int thread_get_inflight_fd( struct thread *thread, int client );
diff --git a/server/timer.c b/server/timer.c
index 85cf080..2db8606 100644
--- a/server/timer.c
+++ b/server/timer.c
@@ -94,7 +94,7 @@
/* queue an APC */
if (timer->thread)
{
- if (!thread_queue_apc( timer->thread, &timer->obj, timer->callback, APC_TIMER, 0, 3,
+ if (!thread_queue_apc( timer->thread, &timer->obj, timer->callback, APC_TIMER, 0,
(void *)timer->when.tv_sec, (void *)timer->when.tv_usec, timer->arg))
{
release_object( timer->thread );
diff --git a/server/trace.c b/server/trace.c
index 9f46615..93b3de8 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -157,21 +157,6 @@
remove_data( size );
}
-static void dump_varargs_ptrs( size_t size )
-{
- void * const *data = cur_data;
- size_t len = size / sizeof(*data);
-
- fputc( '{', stderr );
- while (len > 0)
- {
- fprintf( stderr, "%p", *data++ );
- if (--len) fputc( ',', stderr );
- }
- fputc( '}', stderr );
- remove_data( size );
-}
-
static void dump_varargs_user_handles( size_t size )
{
const user_handle_t *data = cur_data;
@@ -623,7 +608,9 @@
fprintf( stderr, " handle=%p,", req->handle );
fprintf( stderr, " user=%d,", req->user );
fprintf( stderr, " func=%p,", req->func );
- fprintf( stderr, " param=%p", req->param );
+ fprintf( stderr, " arg1=%p,", req->arg1 );
+ fprintf( stderr, " arg2=%p,", req->arg2 );
+ fprintf( stderr, " arg3=%p", req->arg3 );
}
static void dump_get_apc_request( const struct get_apc_request *req )
@@ -635,8 +622,9 @@
{
fprintf( stderr, " func=%p,", req->func );
fprintf( stderr, " type=%d,", req->type );
- fprintf( stderr, " args=" );
- dump_varargs_ptrs( cur_size );
+ fprintf( stderr, " arg1=%p,", req->arg1 );
+ fprintf( stderr, " arg2=%p,", req->arg2 );
+ fprintf( stderr, " arg3=%p", req->arg3 );
}
static void dump_close_handle_request( const struct close_handle_request *req )