Async IO immediate completion via GetOverlappedResult()

Martin Wilck Martin.Wilck at fujitsu-siemens.com
Wed Apr 3 09:26:33 CST 2002


PATCH: async-immediate.diff

This patch uses a more elegant and (IMO) more wine-ish method to check for
possible immediate completion of asynchronous IO requests in ReadFile() and
WriteFile().

It is a resubmission of my posting as of 2002/01/15.

Patch against: Wine CVS 2002-04-03, with my async-struct patch (see last posting) applied.

Test status: Compiles (no errors/warnings).
        Tested for regular file IO (ok).
        The 2002-01-15 patch has been tested for 16-bit serial IO by Lawson Whitney (ok).

Modified Files:
        files           : file.c

Log message:
        Martin Wilck <Martin.Wilck at Fujitsu-Siemens.com>
        GetOverlappedResult(): Return ERROR_IO_INCOMPLETE if IO still pending (MSDN docs)
        ReadFile() / WriteFile(): Use GetOverlappedResult() to check for immediate completion.

diff -ruNX diffignore CVS/wine/files/file.c MW/wine/files/file.c
--- CVS/wine/files/file.c	Wed Apr  3 16:51:21 2002
+++ MW/wine/files/file.c	Wed Apr  3 17:01:37 2002
@@ -1398,7 +1398,8 @@
     if(lpTransferred)
         *lpTransferred = lpOverlapped->InternalHigh;

-    SetLastError(lpOverlapped->Internal);
+    SetLastError ( lpOverlapped->Internal == STATUS_PENDING ?
+                   ERROR_IO_INCOMPLETE : lpOverlapped->Internal );

     return (r==WAIT_OBJECT_0);
 }
@@ -1593,41 +1594,21 @@
             SetLastError(ERROR_INVALID_PARAMETER);
             return FALSE;
         }
-
-        /* see if we can read some data already (this shouldn't block) */
-        result = pread( unix_handle, buffer, bytesToRead, OVERLAPPED_OFFSET(overlapped) );
-        if ((result < 0) && (errno == ESPIPE))
-            result = read( unix_handle, buffer, bytesToRead );
-        close(unix_handle);
-
-        if(result<0)
-        {
-            if( (errno!=EAGAIN) && (errno!=EINTR) &&
-                ((errno != EFAULT) || IsBadWritePtr( buffer, bytesToRead )) )
-            {
-                FILE_SetDosError();
-                return FALSE;
-            }
-            else
-                result = 0;
-        }

-        /* if we read enough to keep the app happy, then return now */
-        if(result>=bytesToRead)
-        {
-            *bytesRead = result;
-            return TRUE;
-        }
-
-        /* at last resort, do an overlapped read */
-        overlapped->InternalHigh = result;
+        close(unix_handle);
+        overlapped->InternalHigh = 0;

         if(!FILE_ReadFileEx(hFile, buffer, bytesToRead, overlapped, NULL, overlapped->hEvent))
             return FALSE;

-        /* fail on return, with ERROR_IO_PENDING */
-        SetLastError(ERROR_IO_PENDING);
-        return FALSE;
+        if ( !GetOverlappedResult (hFile, overlapped, bytesRead, FALSE) )
+        {
+            if ( GetLastError() == ERROR_IO_INCOMPLETE )
+                SetLastError ( ERROR_IO_PENDING );
+            return FALSE;
+        }
+
+        return TRUE;
     }
     if (flags & FD_FLAG_TIMEOUT)
     {
@@ -1807,43 +1788,20 @@
             return FALSE;
         }

-        /* see if we can write some data already (this shouldn't block) */
-
-        result = pwrite( unix_handle, buffer, bytesToWrite, OVERLAPPED_OFFSET (overlapped) );
-        if ((result < 0) && (errno == ESPIPE))
-            result = write( unix_handle, buffer, bytesToWrite );
-
         close(unix_handle);
+        overlapped->InternalHigh = 0;

-        if(result<0)
-        {
-            if( (errno!=EAGAIN) && (errno!=EINTR) &&
-                ((errno != EFAULT) || IsBadReadPtr( buffer, bytesToWrite )) )
-            {
-                FILE_SetDosError();
-                return FALSE;
-            }
-            else
-                result = 0;
-        }
-
-        /* if we wrote enough to keep the app happy, then return now */
-        if(result>=bytesToWrite)
-        {
-            *bytesWritten = result;
-            return TRUE;
-        }
-
-        /* at last resort, do an overlapped read */
-        overlapped->Internal     = STATUS_PENDING;
-        overlapped->InternalHigh = result;
-
         if(!FILE_WriteFileEx(hFile, buffer, bytesToWrite, overlapped, NULL, overlapped->hEvent))
             return FALSE;

-        /* fail on return, with ERROR_IO_PENDING */
-        SetLastError(ERROR_IO_PENDING);
-        return FALSE;
+        if ( !GetOverlappedResult (hFile, overlapped, bytesWritten, FALSE) )
+        {
+            if ( GetLastError() == ERROR_IO_INCOMPLETE )
+                SetLastError ( ERROR_IO_PENDING );
+            return FALSE;
+        }
+
+        return TRUE;
     }

     switch(type)





More information about the wine-patches mailing list