Alexandre Julliard : kernel32: Rewrite GetOverlappedResult for the new async I/O behavior.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Jun 5 05:48:12 CDT 2007


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon Jun  4 23:03:15 2007 +0200

kernel32: Rewrite GetOverlappedResult for the new async I/O behavior.

---

 dlls/kernel32/file.c       |   67 ++++++++++----------------------------------
 dlls/kernel32/tests/file.c |    2 -
 2 files changed, 15 insertions(+), 54 deletions(-)

diff --git a/dlls/kernel32/file.c b/dlls/kernel32/file.c
index be8ca63..a3d6942 100644
--- a/dlls/kernel32/file.c
+++ b/dlls/kernel32/file.c
@@ -539,17 +539,11 @@ BOOL WINAPI WriteFile( HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite,
  *
  *  If successful (and relevant) lpTransferred will hold the number of
  *   bytes transferred during the async operation.
- *
- * BUGS
- *
- * Currently only works for WaitCommEvent, ReadFile, WriteFile
- *   with communications ports.
- *
  */
 BOOL WINAPI GetOverlappedResult(HANDLE hFile, LPOVERLAPPED lpOverlapped,
                                 LPDWORD lpTransferred, BOOL bWait)
 {
-    DWORD r = WAIT_OBJECT_0;
+    NTSTATUS status;
 
     TRACE( "(%p %p %p %x)\n", hFile, lpOverlapped, lpTransferred, bWait );
 
@@ -558,57 +552,26 @@ BOOL WINAPI GetOverlappedResult(HANDLE hFile, LPOVERLAPPED lpOverlapped,
         ERR("lpOverlapped was null\n");
         return FALSE;
     }
-    if ( bWait )
+
+    status = lpOverlapped->Internal;
+    if (status == STATUS_PENDING)
     {
-        if ( lpOverlapped->hEvent )
+        if (!bWait)
         {
-            do
-            {
-                TRACE( "waiting on %p\n", lpOverlapped );
-                r = WaitForSingleObjectEx( lpOverlapped->hEvent, INFINITE, TRUE );
-                TRACE( "wait on %p returned %d\n", lpOverlapped, r );
-            } while ( r == WAIT_IO_COMPLETION );
+            SetLastError( ERROR_IO_INCOMPLETE );
+            return FALSE;
         }
-        else
-        {
-            /* busy loop */
-            while ( ((volatile OVERLAPPED*)lpOverlapped)->Internal == STATUS_PENDING )
-                Sleep( 10 );
-        }
-    }
-    else if ( lpOverlapped->Internal == STATUS_PENDING )
-    {
-        /* Wait in order to give APCs a chance to run. */
-        /* This is cheating, so we must set the event again in case of success -
-           it may be a non-manual reset event. */
-        do
-        {
-            TRACE( "waiting on %p\n", lpOverlapped );
-            r = WaitForSingleObjectEx( lpOverlapped->hEvent, 0, TRUE );
-            TRACE( "wait on %p returned %d\n", lpOverlapped, r );
-        } while ( r == WAIT_IO_COMPLETION );
-        if ( r == WAIT_OBJECT_0 && lpOverlapped->hEvent )
-            NtSetEvent( lpOverlapped->hEvent, NULL );
-    }
-    if ( r == WAIT_FAILED )
-    {
-        WARN("wait operation failed\n");
-        return FALSE;
+
+        if (WaitForSingleObject( lpOverlapped->hEvent ? lpOverlapped->hEvent : hFile,
+                                 INFINITE ) == WAIT_FAILED)
+            return FALSE;
+        status = lpOverlapped->Internal;
     }
+
     if (lpTransferred) *lpTransferred = lpOverlapped->InternalHigh;
 
-    switch ( lpOverlapped->Internal )
-    {
-    case STATUS_SUCCESS:
-        return TRUE;
-    case STATUS_PENDING:
-        SetLastError( ERROR_IO_INCOMPLETE );
-        if ( bWait ) ERR("PENDING status after waiting!\n");
-        return FALSE;
-    default:
-        SetLastError( RtlNtStatusToDosError( lpOverlapped->Internal ) );
-        return FALSE;
-    }
+    if (status) SetLastError( RtlNtStatusToDosError(status) );
+    return !status;
 }
 
 /***********************************************************************
diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c
index 89cf0a2..e9f97f5 100644
--- a/dlls/kernel32/tests/file.c
+++ b/dlls/kernel32/tests/file.c
@@ -1768,9 +1768,7 @@ static void test_overlapped(void)
     ov.Internal = STATUS_PENDING;
     ov.InternalHigh = 0xabcd;
     r = GetOverlappedResult(0, &ov, &result, 0);
-    todo_wine {
     ok( GetLastError() == ERROR_IO_INCOMPLETE, "wrong error %u\n", GetLastError() );
-    }
     ok( r == FALSE, "should return false\n");
     ok( result == 0, "wrong result %u\n", result );
 




More information about the wine-cvs mailing list