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

Alexandre Julliard julliard at wine.codeweavers.com
Fri May 4 07:11:08 CDT 2007


Module: wine
Branch: master
Commit: 46fe7177c108bbb925047a7a4ec509cb323d3e49
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=46fe7177c108bbb925047a7a4ec509cb323d3e49

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu May  3 17:44:32 2007 +0200

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

---

 dlls/ntdll/file.c   |   23 +----------------------
 server/named_pipe.c |   21 ++++++++++++++++-----
 2 files changed, 17 insertions(+), 27 deletions(-)

diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 02a175b..c41d387 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -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 );
diff --git a/server/named_pipe.c b/server/named_pipe.c
index a034436..6dba1f3 100644
--- a/server/named_pipe.c
+++ b/server/named_pipe.c
@@ -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 )))
+                if (!pipe->waiters && !(pipe->waiters = create_async_queue( NULL ))) goto done;
+
+                if (!async_data->event && !async_data->apc)
                 {
-                    release_object( pipe );
-                    return 0;
+                    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 = 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:




More information about the wine-cvs mailing list