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