Make ConnectNamedPipe work in overlapped mode.
diff --git a/server/named_pipe.c b/server/named_pipe.c index edc92e8..57013d9 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c
@@ -48,7 +48,9 @@ struct named_pipe *pipe; struct pipe_user *next; struct pipe_user *prev; - struct event *event; + void *thread; + void *func; + void *overlapped; }; struct named_pipe @@ -122,18 +124,28 @@ assert( !pipe->users ); } +static void notify_waiter( struct pipe_user *user, unsigned int status) +{ + 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); + } + user->thread = NULL; + user->func = NULL; + user->overlapped=NULL; +} + static void pipe_user_destroy( struct object *obj) { struct pipe_user *user = (struct pipe_user *)obj; assert( obj->ops == &pipe_user_ops ); - if(user->event) - { - /* FIXME: signal waiter of failure */ - release_object(user->event); - user->event = NULL; - } + if(user->overlapped) + notify_waiter(user,STATUS_HANDLES_CLOSED); + if(user->other) { close(user->other->obj.fd); @@ -217,8 +229,10 @@ user->pipe = pipe; user->state = ps_none; - user->event = NULL; /* thread wait on this pipe */ user->other = NULL; + user->thread = NULL; + user->func = NULL; + user->overlapped = NULL; /* add to list of pipe users */ if ((user->next = pipe->users)) user->next->prev = user; @@ -301,9 +315,7 @@ if( (user = create_pipe_user (pipe, fds[1])) ) { partner->obj.fd = fds[0]; - set_event(partner->event); - release_object(partner->event); - partner->event = NULL; + notify_waiter(partner,STATUS_SUCCESS); partner->state = ps_connected_server; partner->other = user; user->state = ps_connected_client; @@ -334,7 +346,6 @@ DECL_HANDLER(connect_named_pipe) { struct pipe_user *user, *partner; - struct event *event; user = get_pipe_user_obj(current->process, req->handle, 0); if(!user) @@ -347,16 +358,14 @@ else { user->state = ps_wait_open; - event = get_event_obj(current->process, req->event, 0); - if(event) - user->event = event; + user->thread = current; + user->func = req->func; + user->overlapped = req->overlapped; /* notify all waiters that a pipe just became available */ while( (partner = find_partner(user->pipe,ps_wait_connect)) ) { - set_event(partner->event); - release_object(partner->event); - partner->event = NULL; + notify_waiter(partner,STATUS_SUCCESS); release_object(partner); release_object(partner); } @@ -367,13 +376,8 @@ DECL_HANDLER(wait_named_pipe) { - struct event *event; struct named_pipe *pipe; - event = get_event_obj(current->process, req->event, 0); - if(!event) - return; - pipe = create_named_pipe( get_req_data(req), get_req_data_size(req) ); if( pipe ) { @@ -385,7 +389,10 @@ set_error(STATUS_SUCCESS); if( (partner = find_partner(pipe,ps_wait_open)) ) { - set_event(event); + /* 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); release_object(partner); } else @@ -394,8 +401,10 @@ if( (user = create_pipe_user (pipe, -1)) ) { - user->event = (struct event *)grab_object( event ); user->state = ps_wait_connect; + user->thread = current; + user->func = req->func; + user->overlapped = req->overlapped; /* don't release it */ } } @@ -406,7 +415,6 @@ } release_object(pipe); } - release_object(event); } DECL_HANDLER(disconnect_named_pipe)
diff --git a/server/protocol.def b/server/protocol.def index 07c7f79..5e6c8a0 100644 --- a/server/protocol.def +++ b/server/protocol.def
@@ -1392,14 +1392,16 @@ /* Connect to a named pipe */ @REQ(connect_named_pipe) handle_t handle; - handle_t event; /* set this event when it's ready */ + void* overlapped; + void* func; @END /* Wait for a named pipe */ @REQ(wait_named_pipe) unsigned int timeout; - handle_t event; /* set this event when it's ready */ + void* overlapped; + void* func; VARARG(filename,string); /* pipe name */ @END
diff --git a/server/trace.c b/server/trace.c index ba98c0a..012286b 100644 --- a/server/trace.c +++ b/server/trace.c
@@ -1661,13 +1661,15 @@ static void dump_connect_named_pipe_request( const struct connect_named_pipe_request *req ) { fprintf( stderr, " handle=%d,", req->handle ); - fprintf( stderr, " event=%d", req->event ); + fprintf( stderr, " overlapped=%p,", req->overlapped ); + fprintf( stderr, " func=%p", req->func ); } static void dump_wait_named_pipe_request( const struct wait_named_pipe_request *req ) { fprintf( stderr, " timeout=%08x,", req->timeout ); - fprintf( stderr, " event=%d,", req->event ); + fprintf( stderr, " overlapped=%p,", req->overlapped ); + fprintf( stderr, " func=%p,", req->func ); fprintf( stderr, " filename=" ); cur_pos += dump_varargs_string( req ); }