Alexandre Julliard : server: Always return STATUS_PENDING when an async I/ O operation has been queued.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Mar 27 06:58:40 CDT 2007


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon Mar 26 19:13:21 2007 +0200

server: Always return STATUS_PENDING when an async I/O operation has been queued.

---

 dlls/ntdll/file.c    |   13 ++++++-------
 dlls/ws2_32/socket.c |   20 ++++++++------------
 server/fd.c          |    5 ++---
 server/serial.c      |    1 +
 server/sock.c        |    1 +
 5 files changed, 18 insertions(+), 22 deletions(-)

diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 45786b0..6873e0e 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -282,14 +282,13 @@ static ULONG fileio_queue_async(async_fileio* fileio, IO_STATUS_BLOCK* iosb,
     }
     SERVER_END_REQ;
 
-    if ( status ) iosb->u.Status = status;
-    if ( iosb->u.Status != STATUS_PENDING )
+    if (status != STATUS_PENDING)
     {
+        iosb->u.Status = status;
         (apc)( fileio, iosb, iosb->u.Status );
-        return iosb->u.Status;
     }
-    NtCurrentTeb()->num_async_io++;
-    return STATUS_SUCCESS;
+    else NtCurrentTeb()->num_async_io++;
+    return status;
 }
 
 /***********************************************************************
@@ -531,7 +530,7 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
 
         io_status->u.Status = STATUS_PENDING;
         ret = fileio_queue_async(fileio, io_status, TRUE);
-        if (ret != STATUS_SUCCESS)
+        if (ret != STATUS_PENDING)
         {
             if (flags & FD_FLAG_TIMEOUT) NtClose(hEvent);
             return ret;
@@ -762,7 +761,7 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
         io_status->Information = 0;
         io_status->u.Status = STATUS_PENDING;
         ret = fileio_queue_async(fileio, io_status, FALSE);
-        if (ret != STATUS_SUCCESS)
+        if (ret != STATUS_PENDING)
         {
             if (flags & FD_FLAG_TIMEOUT) NtClose(hEvent);
             return ret;
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 4ad025e..ce57f7d 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -1150,6 +1150,7 @@ static ULONG ws2_queue_async(struct ws2_async* wsa, IO_STATUS_BLOCK* iosb)
     default: FIXME("Unknown internal mode (%d)\n", wsa->mode); return STATUS_INVALID_PARAMETER;
     }
 
+    iosb->u.Status = STATUS_PENDING;
     SERVER_START_REQ( register_async )
     {
         req->handle = wsa->hSocket;
@@ -1163,18 +1164,13 @@ static ULONG ws2_queue_async(struct ws2_async* wsa, IO_STATUS_BLOCK* iosb)
     }
     SERVER_END_REQ;
 
-    if ( status ) iosb->u.Status = status;
-    if ( iosb->u.Status != STATUS_PENDING )
+    if (status != STATUS_PENDING)
     {
-        /* Note: we get here a non zero status when we couldn't queue the async
-         * in the server. Therefore, we simply terminate the async.
-         */
-        status = iosb->u.Status;
+        iosb->u.Status = status;
         ws2_async_terminate(wsa, iosb);
-        return status;
     }
-    NtCurrentTeb()->num_async_io++;
-    return STATUS_SUCCESS;
+    else NtCurrentTeb()->num_async_io++;
+    return status;
 }
 
 /***********************************************************************
@@ -1500,7 +1496,7 @@ static int WS2_register_async_shutdown( SOCKET s, enum ws2_mode mode )
 
     /* Hack: this will cause ws2_async_terminate() to free the overlapped structure */
     wsa->user_overlapped = NULL;
-    if ( (ret = ws2_queue_async( wsa, iosb )) )
+    if ((ret = ws2_queue_async( wsa, iosb )) != STATUS_PENDING)
     {
         err = NtStatusToWSAError( ret );
         goto out;
@@ -2843,7 +2839,7 @@ INT WINAPI WSASendTo( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
             goto err_free;
         }
 
-        if ( ( ret = ws2_queue_async( wsa, iosb ) ) )
+        if ((ret = ws2_queue_async( wsa, iosb )) != STATUS_PENDING)
         {
             err = NtStatusToWSAError( ret );
 
@@ -4349,7 +4345,7 @@ INT WINAPI WSARecvFrom( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
             goto err_free;
         }
 
-        if ( ( ret = ws2_queue_async( wsa, iosb )) )
+        if ((ret = ws2_queue_async( wsa, iosb )) != STATUS_PENDING)
         {
             err = NtStatusToWSAError( ret );
 
diff --git a/server/fd.c b/server/fd.c
index fba6907..bf5f2e0 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -1742,6 +1742,7 @@ void fd_queue_async_timeout( struct fd *fd, const async_data_t *data, int type,
     }
 
     if (!create_async( current, timeout, queue, data )) return;
+    set_error( STATUS_PENDING );
 
     /* Check if the new pending request can be served immediately */
     events = check_fd_events( fd, fd->fd_ops->get_poll_events( fd ) );
@@ -1937,9 +1938,7 @@ DECL_HANDLER(register_async)
      * 3. Carry out any operations necessary to adjust the object's poll events
      *    Usually: set_elect_events (obj, obj->ops->get_poll_events()).
      * 4. When the async request is triggered, then send back (with a proper APC)
-     *    the trigger (STATUS_ALERTED) to the thread that posted the request. 
-     *    async_destroy() is to be called: it will both notify the sender about
-     *    the trigger and destroy the request by itself
+     *    the trigger (STATUS_ALERTED) to the thread that posted the request.
      * See also the implementations in file.c, serial.c, and sock.c.
      */
 
diff --git a/server/serial.c b/server/serial.c
index d459426..7b92fac 100644
--- a/server/serial.c
+++ b/server/serial.c
@@ -273,6 +273,7 @@ static void serial_queue_async( struct fd *fd, const async_data_t *data, int typ
 
     add_timeout( &when, timeout );
     if (!create_async( current, timeout ? &when : NULL, queue, data )) return;
+    set_error( STATUS_PENDING );
 
     /* Check if the new pending request can be served immediately */
     events = check_fd_events( fd, serial_get_poll_events( fd ) );
diff --git a/server/sock.c b/server/sock.c
index f1b7255..009d37e 100644
--- a/server/sock.c
+++ b/server/sock.c
@@ -545,6 +545,7 @@ static void sock_queue_async( struct fd *fd, const async_data_t *data, int type,
     else
     {
         if (!create_async( current, NULL, queue, data )) return;
+        set_error( STATUS_PENDING );
     }
 
     pollev = sock_reselect( sock );




More information about the wine-cvs mailing list