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 polished resubmit of my former posting, without the structural changes that were posted in a separate patch. It is against CVS 2002-01-15, with that former patch (async-struct.diff) applied. It will not apply to clean CVS. It was tested for regular file IO and (even 16 bit) serial IO (thanks 2 Lawson Whitney). No regressions found. ChangeLog: files/file.c: GetOverlappedResult(): Return ERROR_IO_INCOMPLETE if IO still pending (MSDN docs) ReadFile() / WriteFile(): Use GetOverlappedResult() to check for immediate completion. Martin Wilck <Martin.Wilck@Fujitsu-Siemens.com> diff -ruX diffignore MW/wine/files/file.c CVS/wine/files/file.c --- MW/wine/files/file.c Tue Jan 15 19:34:00 2002 +++ CVS/wine/files/file.c Tue Jan 15 19:37:57 2002 @@ -1264,7 +1264,9 @@ if(lpTransferred) *lpTransferred = lpOverlapped->InternalHigh; - SetLastError(lpOverlapped->Internal); + /* This is what the function should return according to MSDN specs */ + if ( lpOverlapped->Internal == STATUS_PENDING ) + SetLastError ( ERROR_IO_INCOMPLETE ); return (r==WAIT_OBJECT_0); } @@ -1498,40 +1500,20 @@ 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; + overlapped->InternalHigh = 0; if(!FILE_ReadFileEx(hFile, buffer, bytesToRead, overlapped, FILE_OverlappedComplete)) 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) { @@ -1711,43 +1693,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(!FILE_WriteFileEx(hFile, buffer, bytesToWrite, overlapped, FILE_OverlappedComplete)) + return FALSE; - /* if we wrote enough to keep the app happy, then return now */ - if(result>=bytesToWrite) + if ( !GetOverlappedResult (hFile, overlapped, bytesWritten, FALSE) ) { - *bytesWritten = result; - return TRUE; + if ( GetLastError() == ERROR_IO_INCOMPLETE ) + SetLastError ( ERROR_IO_PENDING ); + return FALSE; } - - /* at last resort, do an overlapped read */ - overlapped->Internal = STATUS_PENDING; - overlapped->InternalHigh = result; - if(!FILE_WriteFileEx(hFile, buffer, bytesToWrite, overlapped, FILE_OverlappedComplete)) - return FALSE; - - /* fail on return, with ERROR_IO_PENDING */ - SetLastError(ERROR_IO_PENDING); - return FALSE; + return TRUE; } switch(type)