[PATCH:] fix overlapped I/O problems
Hi, The included patch (against CVS 2001-11-08) fixes two problems with overlapped I/O: 1) Overlapped ReadFile() didn't work on normal files because file_get_info() never returned FD_TYPE_OVERLAPPED. 2) According to the MS docs, the lpOverlapped argument's Offset and OffsetHigh fields contain the offset from which to read. This was not honoured by the current implementation which only did sequential reads. Regards, Martin -- Martin Wilck Phone: +49 5251 8 15113 Fujitsu Siemens Computers Fax: +49 5251 8 20409 Heinz-Nixdorf-Ring 1 mailto:Martin.Wilck(a)Fujitsu-Siemens.com D-33106 Paderborn http://www.fujitsu-siemens.com/primergy Index: files/file.c =================================================================== RCS file: /home/wine/wine/files/file.c,v retrieving revision 1.119 diff -u -r1.119 file.c --- files/file.c 2001/10/24 00:23:25 1.119 +++ files/file.c 2001/11/09 17:35:29 @@ -1275,6 +1275,7 @@ { LPOVERLAPPED lpOverlapped = ovp->lpOverlapped; int result, r; + off_t ofs; TRACE("%p %p %08x\n", lpOverlapped, ovp->buffer, events ); @@ -1294,9 +1295,18 @@ goto async_end; } + ofs = lpOverlapped->Offset + ((off_t)lpOverlapped->OffsetHigh << 32) + + lpOverlapped->InternalHigh; + /* check to see if the data is ready (non-blocking) */ - result = read(ovp->fd, &ovp->buffer[lpOverlapped->InternalHigh], - ovp->count - lpOverlapped->InternalHigh); + /* Use the offset as given in the Overlapped structure */ + result = pread (ovp->fd, &ovp->buffer[lpOverlapped->InternalHigh], + ovp->count - lpOverlapped->InternalHigh, ofs); + + /* If pread fails, try a normal read */ + if (result == -1 && errno == ESPIPE) + result = read (ovp->fd, &ovp->buffer[lpOverlapped->InternalHigh], + ovp->count - lpOverlapped->InternalHigh); if ( (result<0) && ((errno == EAGAIN) || (errno == EINTR))) { @@ -1444,6 +1454,7 @@ { int unix_handle, result; DWORD type; + off_t ofs; TRACE("%d %p %ld %p %p\n", hFile, buffer, bytesToRead, bytesRead, overlapped ); @@ -1466,7 +1477,11 @@ } /* see if we can read some data already (this shouldn't block) */ - result = read( unix_handle, buffer, bytesToRead ); + ofs = overlapped->Offset + ((off_t)overlapped->OffsetHigh << 32); + /* Try using the user-given offset first, fall back to read otherwise */ + result = pread( unix_handle, buffer, bytesToRead, ofs); + if (result == -1 && errno == ESPIPE) + result = read( unix_handle, buffer, bytesToRead ); close(unix_handle); if(result<0) Index: server/file.c =================================================================== RCS file: /home/wine/wine/server/file.c,v retrieving revision 1.48 diff -u -r1.48 file.c --- server/file.c 2001/10/24 00:23:26 1.48 +++ server/file.c 2001/11/09 17:35:29 @@ -307,6 +307,10 @@ req->index_low = st.st_ino; req->serial = 0; /* FIXME */ } + + if (file->flags & FILE_FLAG_OVERLAPPED) + return FD_TYPE_OVERLAPPED; + return FD_TYPE_DEFAULT; }
participants (1)
-
Martin Wilck