[Bug 50591] New: ReadFile schedules async read when ReadIntervalTimeout is MAXDWORD

WineHQ Bugzilla wine-bugs at winehq.org
Sat Jan 30 11:18:45 CST 2021


https://bugs.winehq.org/show_bug.cgi?id=50591

            Bug ID: 50591
           Summary: ReadFile schedules async read when ReadIntervalTimeout
                    is MAXDWORD
           Product: Wine
           Version: 6.1
          Hardware: x86-64
                OS: Linux
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: ntdll
          Assignee: wine-bugs at winehq.org
          Reporter: aaron.knister at gmail.com
      Distribution: ---

Created attachment 69269
  --> https://bugs.winehq.org/attachment.cgi?id=69269
ntdll: NtReadFile async reads always return success when avail_mode TRUE

TeraTerm is ending up with missing data when it reads from a COM/Serial port.

TeraTerm sets ReadIntervalTimeout to MAXDWORD and then calls ReadFile
asynchronously, and if there's pending IO it waits 1 second for the overlapped
struct event to be signalled. If the signal is received, it processes the
received I/O, else continues on and will perform another ReadFile. This is the
code snippet:

if (!ReadFile(cv->ComID,&(cv->InBuff[cv->InBuffCount]), 
    InBuffSize-cv->InBuffCount,&C,&rol)) {
        if (GetLastError() == ERROR_IO_PENDING) {
            if (WaitForSingleObject(rol.hEvent, 1000) != WAIT_OBJECT_0) {
                C = 0;
            }
            else {
                GetOverlappedResult(cv->ComID,&rol,&C,FALSE);
         }
}

What's happening in WINE, is ReadFile returns non-zero with ERROR_IO_PENDING
and the WaitForSingleObject times out. The asynchronous read *does* complete
after the timeout, but by that point the application has given up and moved on.
I initially thought the application was at fault, because it should retry if
the wait times out. However, in the documentation for ReadFile it points to
documentation about COMMTIMEOUTS
(https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-commtimeouts)
which says the following:

A value of MAXDWORD, combined with zero values for both the
ReadTotalTimeoutConstant and ReadTotalTimeoutMultiplier members, specifies that
the read operation is to return immediately with the bytes that have already
been received, even if no bytes have been received.

To me, that means Wine ought not to be triggering an asynchronous read when the
comm timeout parameters are set as indicated above.

I coded a simple fix, which is in NtReadFile, if avail_mode is TRUE return
success even if no bytes were read. See attached patch. It works for TeraTerm,
I have no idea if it causes other regressions.

-- 
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.



More information about the wine-bugs mailing list