Alexandre Julliard : ntdll: Simplify the async read/ write code now that most of the work is done in the server.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Apr 10 14:58:05 CDT 2007


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Apr 10 17:19:24 2007 +0200

ntdll: Simplify the async read/write code now that most of the work is done in the server.

---

 dlls/ntdll/file.c |  121 +++++++++++++++++++++++++++-------------------------
 1 files changed, 63 insertions(+), 58 deletions(-)

diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index f3ba690..078e4fe 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -236,57 +236,24 @@ NTSTATUS WINAPI NtCreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATTRIB
 /***********************************************************************
  *                  Asynchronous file I/O                              *
  */
-static NTSTATUS FILE_AsyncReadService(void*, PIO_STATUS_BLOCK, NTSTATUS);
-static NTSTATUS FILE_AsyncWriteService(void*, PIO_STATUS_BLOCK, NTSTATUS);
 
-typedef struct async_fileio
+typedef struct
 {
     HANDLE              handle;
-    PIO_APC_ROUTINE     apc;
-    void*               apc_user;
     char*               buffer;
     unsigned int        already;
     unsigned int        count;
     BOOL                avail_mode;
-    HANDLE              event;
-} async_fileio;
+} async_fileio_read;
 
-static void fileio_terminate(async_fileio *fileio, IO_STATUS_BLOCK* iosb, NTSTATUS status)
+typedef struct
 {
-    TRACE("data: %p\n", fileio);
-
-    iosb->u.Status = status;
-    iosb->Information = fileio->already;
-    RtlFreeHeap( GetProcessHeap(), 0, fileio );
-}
-
-
-static ULONG fileio_queue_async(async_fileio* fileio, IO_STATUS_BLOCK* iosb, 
-                                BOOL do_read)
-{
-    NTSTATUS status;
-
-    SERVER_START_REQ( register_async )
-    {
-        req->handle = fileio->handle;
-        req->async.callback = do_read ? FILE_AsyncReadService : FILE_AsyncWriteService;
-        req->async.iosb     = iosb;
-        req->async.arg      = fileio;
-        req->async.apc      = fileio->apc;
-        req->async.apc_arg  = fileio->apc_user;
-        req->async.event    = fileio->event;
-        req->type = do_read ? ASYNC_TYPE_READ : ASYNC_TYPE_WRITE;
-        req->count = (fileio->count < fileio->already) ? 0 : fileio->count - fileio->already;
-        status = wine_server_call( req );
-    }
-    SERVER_END_REQ;
+    HANDLE              handle;
+    const char         *buffer;
+    unsigned int        already;
+    unsigned int        count;
+} async_fileio_write;
 
-    if (status != STATUS_PENDING)
-        fileio_terminate( fileio, iosb, status );
-    else
-        NtCurrentTeb()->num_async_io++;
-    return status;
-}
 
 /***********************************************************************
  *           FILE_GetNtStatus(void)
@@ -339,7 +306,7 @@ NTSTATUS FILE_GetNtStatus(void)
  */
 static NTSTATUS FILE_AsyncReadService(void *user, PIO_STATUS_BLOCK iosb, NTSTATUS status)
 {
-    async_fileio *fileio = (async_fileio*)user;
+    async_fileio_read *fileio = user;
     int fd, needs_close, result;
 
     TRACE("%p %p 0x%x\n", iosb, fileio->buffer, status);
@@ -394,7 +361,12 @@ static NTSTATUS FILE_AsyncReadService(void *user, PIO_STATUS_BLOCK iosb, NTSTATU
         if (fileio->already) status = STATUS_SUCCESS;
         break;
     }
-    if (status != STATUS_PENDING) fileio_terminate(fileio, iosb, status);
+    if (status != STATUS_PENDING)
+    {
+        iosb->u.Status = status;
+        iosb->Information = fileio->already;
+        RtlFreeHeap( GetProcessHeap(), 0, fileio );
+    }
     return status;
 }
 
@@ -580,7 +552,7 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
 
         if (flags & FD_FLAG_OVERLAPPED)
         {
-            async_fileio *fileio;
+            async_fileio_read *fileio;
 
             if (total && (flags & FD_FLAG_AVAILABLE))
             {
@@ -588,7 +560,7 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
                 goto done;
             }
 
-            if (!(fileio = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(async_fileio))))
+            if (!(fileio = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(*fileio))))
             {
                 status = STATUS_NO_MEMORY;
                 goto done;
@@ -596,12 +568,26 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
             fileio->handle = hFile;
             fileio->already = total;
             fileio->count = length;
-            fileio->apc = apc;
-            fileio->apc_user = apc_user;
             fileio->buffer = buffer;
             fileio->avail_mode = (flags & FD_FLAG_AVAILABLE);
-            fileio->event = hEvent;
-            status = fileio_queue_async(fileio, io_status, TRUE);
+
+            SERVER_START_REQ( register_async )
+            {
+                req->handle = hFile;
+                req->type   = ASYNC_TYPE_READ;
+                req->count  = length;
+                req->async.callback = FILE_AsyncReadService;
+                req->async.iosb     = io_status;
+                req->async.arg      = fileio;
+                req->async.apc      = apc;
+                req->async.apc_arg  = apc_user;
+                req->async.event    = hEvent;
+                status = wine_server_call( req );
+            }
+            SERVER_END_REQ;
+
+            if (status != STATUS_PENDING) RtlFreeHeap( GetProcessHeap(), 0, fileio );
+            else NtCurrentTeb()->num_async_io++;
             goto done;
         }
         else  /* synchronous read, wait for the fd to become ready */
@@ -662,7 +648,7 @@ done:
  */
 static NTSTATUS FILE_AsyncWriteService(void *user, IO_STATUS_BLOCK *iosb, NTSTATUS status)
 {
-    async_fileio *fileio = user;
+    async_fileio_write *fileio = user;
     int result, fd, needs_close;
     enum server_fd_type type;
 
@@ -701,7 +687,12 @@ static NTSTATUS FILE_AsyncWriteService(void *user, IO_STATUS_BLOCK *iosb, NTSTAT
         if (fileio->already) status = STATUS_SUCCESS;
         break;
     }
-    if (status != STATUS_PENDING) fileio_terminate(fileio, iosb, status);
+    if (status != STATUS_PENDING)
+    {
+        iosb->u.Status = status;
+        iosb->Information = fileio->already;
+        RtlFreeHeap( GetProcessHeap(), 0, fileio );
+    }
     return status;
 }
 
@@ -799,9 +790,9 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
 
         if (flags & FD_FLAG_OVERLAPPED)
         {
-            async_fileio *fileio;
+            async_fileio_write *fileio;
 
-            if (!(fileio = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(async_fileio))))
+            if (!(fileio = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(*fileio))))
             {
                 status = STATUS_NO_MEMORY;
                 goto done;
@@ -809,11 +800,25 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
             fileio->handle = hFile;
             fileio->already = total;
             fileio->count = length;
-            fileio->apc = apc;
-            fileio->apc_user = apc_user;
-            fileio->buffer = (void*)buffer;
-            fileio->event = hEvent;
-            status = fileio_queue_async(fileio, io_status, FALSE);
+            fileio->buffer = buffer;
+
+            SERVER_START_REQ( register_async )
+            {
+                req->handle = hFile;
+                req->type   = ASYNC_TYPE_WRITE;
+                req->count  = length;
+                req->async.callback = FILE_AsyncWriteService;
+                req->async.iosb     = io_status;
+                req->async.arg      = fileio;
+                req->async.apc      = apc;
+                req->async.apc_arg  = apc_user;
+                req->async.event    = hEvent;
+                status = wine_server_call( req );
+            }
+            SERVER_END_REQ;
+
+            if (status != STATUS_PENDING) RtlFreeHeap( GetProcessHeap(), 0, fileio );
+            else NtCurrentTeb()->num_async_io++;
             goto done;
         }
         else  /* synchronous write, wait for the fd to become ready */




More information about the wine-cvs mailing list