server: Allocate the wait event for FSCTL_PIPE_WAIT on the server side.

oldstable
Alexandre Julliard 2007-05-03 17:44:32 +02:00
parent 63a2372526
commit 46fe7177c1
2 changed files with 19 additions and 29 deletions

View File

@ -1075,28 +1075,6 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
if (!status) status = DIR_unmount_device( handle );
break;
case FSCTL_PIPE_WAIT:
{
HANDLE internal_event = 0;
if(!event && !apc)
{
status = NtCreateEvent(&internal_event, EVENT_ALL_ACCESS, NULL, FALSE, FALSE);
if (status != STATUS_SUCCESS) break;
event = internal_event;
}
status = server_ioctl_file( handle, event, apc, apc_context, io, code,
in_buffer, in_size, out_buffer, out_size );
if (internal_event && status == STATUS_PENDING)
{
while (NtWaitForSingleObject(internal_event, TRUE, NULL) == STATUS_USER_APC) /*nothing*/ ;
status = io->u.Status;
}
if (internal_event) NtClose(internal_event);
}
break;
case FSCTL_PIPE_PEEK:
{
FILE_PIPE_PEEK_BUFFER *buffer = out_buffer;
@ -1173,6 +1151,7 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
break;
case FSCTL_PIPE_LISTEN:
case FSCTL_PIPE_WAIT:
default:
status = server_ioctl_file( handle, event, apc, apc_context, io, code,
in_buffer, in_size, out_buffer, out_size );

View File

@ -846,6 +846,7 @@ static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, c
case FSCTL_PIPE_WAIT:
{
const FILE_PIPE_WAIT_FOR_BUFFER *buffer = data;
obj_handle_t wait_handle = 0;
struct named_pipe *pipe;
struct pipe_server *server;
struct unicode_str name;
@ -867,13 +868,22 @@ static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, c
{
struct async *async;
if (!pipe->waiters && !(pipe->waiters = create_async_queue( NULL )))
{
release_object( pipe );
return 0;
}
if (!pipe->waiters && !(pipe->waiters = create_async_queue( NULL ))) goto done;
if ((async = create_async( current, pipe->waiters, async_data )))
if (!async_data->event && !async_data->apc)
{
async_data_t new_data = *async_data;
if (!(wait_handle = alloc_wait_event( current->process ))) goto done;
new_data.event = wait_handle;
if (!(async = create_async( current, pipe->waiters, &new_data )))
{
close_handle( current->process, wait_handle );
wait_handle = 0;
}
}
else async = create_async( current, pipe->waiters, async_data );
if (async)
{
timeout_t when = buffer->TimeoutSpecified ? buffer->Timeout.QuadPart : pipe->timeout;
async_set_timeout( async, when, STATUS_IO_TIMEOUT );
@ -883,8 +893,9 @@ static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, c
}
else release_object( server );
done:
release_object( pipe );
return 0;
return wait_handle;
}
default: