server: Move the signalling of the named pipe completion event to the server.

This commit is contained in:
Alexandre Julliard 2007-03-21 14:31:54 +01:00
parent 2b6d1fa59b
commit a133ad56f9
2 changed files with 24 additions and 43 deletions

View File

@ -920,14 +920,10 @@ NTSTATUS WINAPI NtDeviceIoControlFile(HANDLE handle, HANDLE event,
/*********************************************************************** /***********************************************************************
* pipe_completion_wait (Internal) * 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); TRACE("for %p, status=%08x\n", iosb, status);
if (iosb)
iosb->u.Status = status; iosb->u.Status = status;
NtSetEvent(event, NULL);
TRACE("done\n");
} }
/************************************************************************** /**************************************************************************
@ -982,21 +978,18 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
req->handle = handle; req->handle = handle;
req->async.callback = pipe_completion_wait; req->async.callback = pipe_completion_wait;
req->async.iosb = io; 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); io->u.Status = wine_server_call(req);
} }
SERVER_END_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 do
io->u.Status = NtWaitForSingleObject(internal_event, TRUE, NULL); io->u.Status = NtWaitForSingleObject(internal_event, TRUE, NULL);
while(io->u.Status == STATUS_USER_APC); while(io->u.Status == STATUS_USER_APC);
} }
}
if (internal_event) NtClose(internal_event); if (internal_event) NtClose(internal_event);
} }
break; break;
@ -1018,23 +1011,19 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
: NMPWAIT_USE_DEFAULT_WAIT; : NMPWAIT_USE_DEFAULT_WAIT;
req->async.callback = pipe_completion_wait; req->async.callback = pipe_completion_wait;
req->async.iosb = io; 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 ); wine_server_add_data( req, buff->Name, buff->NameLength );
io->u.Status = wine_server_call( req ); io->u.Status = wine_server_call( req );
} }
SERVER_END_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 do
io->u.Status = NtWaitForSingleObject(internal_event, TRUE, NULL); io->u.Status = NtWaitForSingleObject(internal_event, TRUE, NULL);
while(io->u.Status == STATUS_USER_APC); while(io->u.Status == STATUS_USER_APC);
} }
}
if (internal_event) NtClose(internal_event); if (internal_event) NtClose(internal_event);
} }
break; break;

View File

@ -826,6 +826,7 @@ DECL_HANDLER(connect_named_pipe)
server->state = ps_wait_open; server->state = ps_wait_open;
create_async( current, NULL, &server->wait_q, &req->async ); create_async( current, NULL, &server->wait_q, &req->async );
async_terminate_queue( &server->pipe->waiters, STATUS_SUCCESS ); async_terminate_queue( &server->pipe->waiters, STATUS_SUCCESS );
set_error( STATUS_PENDING );
break; break;
case ps_connected_server: case ps_connected_server:
assert( server->fd ); assert( server->fd );
@ -865,32 +866,23 @@ DECL_HANDLER(wait_named_pipe)
return; return;
} }
server = find_server( pipe, ps_wait_open ); server = find_server( pipe, ps_wait_open );
if (server) 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 (req->timeout == NMPWAIT_WAIT_FOREVER) 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 else
{ {
struct timeval when = current_time; struct timeval when = current_time;
if (req->timeout == NMPWAIT_USE_DEFAULT_WAIT) add_timeout( &when, pipe->timeout ); if (req->timeout == NMPWAIT_USE_DEFAULT_WAIT) add_timeout( &when, pipe->timeout );
else add_timeout( &when, req->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 ); release_object( pipe );
} }