Module: wine Branch: master Commit: 63a2372526ff534c997d90a0933dcab834b599e3 URL: http://source.winehq.org/git/wine.git/?a=commit;h=63a2372526ff534c997d90a093...
Author: Alexandre Julliard julliard@winehq.org Date: Thu May 3 17:44:05 2007 +0200
server: Allocate the wait event for FSCTL_PIPE_LISTEN on the server side.
---
dlls/ntdll/file.c | 2 +- server/named_pipe.c | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index cb09e96..02a175b 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -1075,7 +1075,6 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc if (!status) status = DIR_unmount_device( handle ); break;
- case FSCTL_PIPE_LISTEN: case FSCTL_PIPE_WAIT: { HANDLE internal_event = 0; @@ -1173,6 +1172,7 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc status = STATUS_SUCCESS; break;
+ case FSCTL_PIPE_LISTEN: default: status = server_ioctl_file( handle, event, apc, apc_context, io, code, in_buffer, in_size, out_buffer, out_size ); diff --git a/server/named_pipe.c b/server/named_pipe.c index 9137bf6..a034436 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -570,11 +570,25 @@ static enum server_fd_type pipe_client_get_fd_type( struct fd *fd ) return FD_TYPE_PIPE; }
+static obj_handle_t alloc_wait_event( struct process *process ) +{ + obj_handle_t handle = 0; + struct event *event = create_event( NULL, NULL, 0, 1, 0 ); + + if (event) + { + handle = alloc_handle( process, event, EVENT_ALL_ACCESS, 0 ); + release_object( event ); + } + return handle; +} + static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data, const void *data, data_size_t size ) { struct pipe_server *server = get_fd_user( fd ); struct async *async; + obj_handle_t wait_handle = 0;
switch(code) { @@ -583,12 +597,26 @@ static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const a { case ps_idle_server: case ps_wait_connect: - set_server_state( server, ps_wait_open ); - if ((async = fd_queue_async( server->ioctl_fd, async_data, ASYNC_TYPE_WAIT, 0 ))) + if (!async_data->event && !async_data->apc) + { + async_data_t new_data = *async_data; + if (!(wait_handle = alloc_wait_event( current->process ))) break; + new_data.event = wait_handle; + if (!(async = fd_queue_async( server->ioctl_fd, &new_data, ASYNC_TYPE_WAIT, 0 ))) + { + close_handle( current->process, wait_handle ); + break; + } + } + else async = fd_queue_async( server->ioctl_fd, async_data, ASYNC_TYPE_WAIT, 0 ); + + if (async) { + set_server_state( server, ps_wait_open ); if (server->pipe->waiters) async_wake_up( server->pipe->waiters, STATUS_SUCCESS ); release_object( async ); set_error( STATUS_PENDING ); + return wait_handle; } break; case ps_connected_server: