From a133ad56f913b13d95bfd217aa627fdda50d5cd4 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 21 Mar 2007 14:31:54 +0100 Subject: [PATCH] server: Move the signalling of the named pipe completion event to the server. --- dlls/ntdll/file.c | 41 +++++++++++++++-------------------------- server/named_pipe.c | 26 +++++++++----------------- 2 files changed, 24 insertions(+), 43 deletions(-) diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index c25e2294cee..0b225833a7f 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -920,14 +920,10 @@ NTSTATUS WINAPI NtDeviceIoControlFile(HANDLE handle, HANDLE event, /*********************************************************************** * pipe_completion_wait (Internal) */ -static void CALLBACK pipe_completion_wait(HANDLE event, PIO_STATUS_BLOCK iosb, ULONG status) +static void CALLBACK pipe_completion_wait(void *arg, PIO_STATUS_BLOCK iosb, ULONG status) { - TRACE("for %p/%p, status=%08x\n", event, iosb, status); - - if (iosb) - iosb->u.Status = status; - NtSetEvent(event, NULL); - TRACE("done\n"); + TRACE("for %p, status=%08x\n", iosb, status); + iosb->u.Status = status; } /************************************************************************** @@ -982,20 +978,17 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc req->handle = handle; req->async.callback = pipe_completion_wait; req->async.iosb = io; - req->async.arg = event ? event : internal_event; + req->async.arg = NULL; + req->async.event = event ? event : internal_event; io->u.Status = wine_server_call(req); } SERVER_END_REQ; - if(io->u.Status == STATUS_SUCCESS) + if (!event && io->u.Status == STATUS_PENDING) { - if(event) io->u.Status = STATUS_PENDING; - else - { - do - io->u.Status = NtWaitForSingleObject(internal_event, TRUE, NULL); - while(io->u.Status == STATUS_USER_APC); - } + do + io->u.Status = NtWaitForSingleObject(internal_event, TRUE, NULL); + while(io->u.Status == STATUS_USER_APC); } if (internal_event) NtClose(internal_event); } @@ -1018,22 +1011,18 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc : NMPWAIT_USE_DEFAULT_WAIT; req->async.callback = pipe_completion_wait; req->async.iosb = io; - req->async.arg = event ? event : internal_event; + req->async.arg = NULL; + req->async.event = event ? event : internal_event; wine_server_add_data( req, buff->Name, buff->NameLength ); io->u.Status = wine_server_call( req ); } SERVER_END_REQ; - if(io->u.Status == STATUS_SUCCESS) + if (!event && io->u.Status == STATUS_PENDING) { - if(event) - io->u.Status = STATUS_PENDING; - else - { - do - io->u.Status = NtWaitForSingleObject(internal_event, TRUE, NULL); - while(io->u.Status == STATUS_USER_APC); - } + do + io->u.Status = NtWaitForSingleObject(internal_event, TRUE, NULL); + while(io->u.Status == STATUS_USER_APC); } if (internal_event) NtClose(internal_event); } diff --git a/server/named_pipe.c b/server/named_pipe.c index 61ddd37f468..a9ca5b11b1b 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -826,6 +826,7 @@ DECL_HANDLER(connect_named_pipe) server->state = ps_wait_open; create_async( current, NULL, &server->wait_q, &req->async ); async_terminate_queue( &server->pipe->waiters, STATUS_SUCCESS ); + set_error( STATUS_PENDING ); break; case ps_connected_server: assert( server->fd ); @@ -865,32 +866,23 @@ DECL_HANDLER(wait_named_pipe) return; } server = find_server( pipe, ps_wait_open ); - if (server) - { - apc_call_t data; - - /* there's already a server waiting for a client to connect */ - memset( &data, 0, sizeof(data) ); - data.type = APC_ASYNC_IO; - data.async_io.func = req->async.callback; - data.async_io.user = req->async.arg; - data.async_io.sb = req->async.iosb; - data.async_io.status = STATUS_SUCCESS; - thread_queue_apc( current, NULL, &data ); - release_object( server ); - } - else + if (!server) { if (req->timeout == NMPWAIT_WAIT_FOREVER) - create_async( current, NULL, &pipe->waiters, &req->async ); + { + if (create_async( current, NULL, &pipe->waiters, &req->async )) + set_error( STATUS_PENDING ); + } else { struct timeval when = current_time; if (req->timeout == NMPWAIT_USE_DEFAULT_WAIT) add_timeout( &when, pipe->timeout ); else add_timeout( &when, req->timeout ); - create_async( current, &when, &pipe->waiters, &req->async ); + if (create_async( current, &when, &pipe->waiters, &req->async )) + set_error( STATUS_PENDING ); } } + else release_object( server ); release_object( pipe ); }