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)
*/
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);
}

View File

@ -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 );
}