From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2155) id DD2A7385E01A; Thu, 26 Mar 2020 11:26:56 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DD2A7385E01A Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Corinna Vinschen To: cygwin-cvs@sourceware.org Subject: [newlib-cygwin] Cygwin: serial: read: if VMIN > 0, wait for VMIN chars in inbound queue X-Act-Checkin: newlib-cygwin X-Git-Author: Corinna Vinschen X-Git-Refname: refs/heads/master X-Git-Oldrev: 2a4b1de773e6159ea8197b6fc3f7e4845479b476 X-Git-Newrev: 082f2513c721e942d0fd563c4dc9117eee3513ab Message-Id: <20200326112656.DD2A7385E01A@sourceware.org> Date: Thu, 26 Mar 2020 11:26:56 +0000 (GMT) X-BeenThere: cygwin-cvs@cygwin.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Cygwin core component git logs List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 26 Mar 2020 11:26:57 -0000 https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=082f2513c721e942d0fd563c4dc9117eee3513ab commit 082f2513c721e942d0fd563c4dc9117eee3513ab Author: Corinna Vinschen Date: Wed Mar 25 12:21:59 2020 +0100 Cygwin: serial: read: if VMIN > 0, wait for VMIN chars in inbound queue Per termios, read waits for MIN chars even if the number of requested bytes is less. This requires to add WaitCommEvent to wait non-busily for MIN chars prior to calling ReadFile, so, reintroduce it. Signed-off-by: Corinna Vinschen Diff: --- winsup/cygwin/fhandler_serial.cc | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/winsup/cygwin/fhandler_serial.cc b/winsup/cygwin/fhandler_serial.cc index b6d1e4f4c..1750a9f97 100644 --- a/winsup/cygwin/fhandler_serial.cc +++ b/winsup/cygwin/fhandler_serial.cc @@ -34,19 +34,20 @@ void __reg3 fhandler_serial::raw_read (void *ptr, size_t& ulen) { OVERLAPPED ov = { 0 }; - DWORD io_err; + DWORD io_err, event; COMSTAT st; DWORD bytes_to_read, read_bytes; ssize_t tot = 0; + bool wait_for_vmin, ret; if (ulen > SSIZE_MAX) ulen = SSIZE_MAX; if (ulen == 0) return; - /* If VMIN > 0 in blocking mode, we have to read at least VMIN chars, - otherwise we're in polling mode and there's no minimum chars. */ - ssize_t minchars = (!is_nonblocking () && vmin_) ? MIN (vmin_, ulen) : 0; + /* If VMIN > 0 in blocking mode, we have to wait for at least VMIN chars. + Otherwise we're in polling mode and there's no minimum chars. */ + ssize_t minchars = is_nonblocking () ? 0 : vmin_; debug_printf ("ulen %ld, vmin_ %u, vtime_ %u", ulen, vmin_, vtime_); @@ -54,6 +55,8 @@ fhandler_serial::raw_read (void *ptr, size_t& ulen) do { + wait_for_vmin = false; + /* First check if chars are already in the inbound queue. */ if (!ClearCommError (get_handle (), &io_err, &st)) goto err; @@ -82,14 +85,22 @@ fhandler_serial::raw_read (void *ptr, size_t& ulen) and don't wait. */ if (st.cbInQue && st.cbInQue >= minchars) bytes_to_read = MIN (st.cbInQue, bytes_to_read); + /* Otherwise, if VMIN > 0, VTIME == 0, we have to wait until + VMIN bytes are available in the inbound queue. */ + else if (minchars && !vtime_) + wait_for_vmin = true; } ResetEvent (ov.hEvent); - if (!ReadFile (get_handle (), ptr, bytes_to_read, &read_bytes, &ov)) + if (wait_for_vmin) + ret = WaitCommEvent (get_handle (), &event, &ov); + else + ret = ReadFile (get_handle (), ptr, bytes_to_read, &read_bytes, &ov); + if (!ret) { if (GetLastError () != ERROR_IO_PENDING) goto err; - if (is_nonblocking ()) + if (!wait_for_vmin && is_nonblocking ()) { CancelIo (get_handle ()); if (!GetOverlappedResult (get_handle (), &ov, &read_bytes, @@ -134,12 +145,15 @@ fhandler_serial::raw_read (void *ptr, size_t& ulen) } } } - tot += read_bytes; - ptr = (void *) ((caddr_t) ptr + read_bytes); - ulen -= read_bytes; - minchars -= read_bytes; - debug_printf ("vtime_ %u, vmin_ %u, read_bytes %u, tot %D", - vtime_, vmin_, read_bytes, tot); + if (!wait_for_vmin) + { + tot += read_bytes; + ptr = (void *) ((caddr_t) ptr + read_bytes); + ulen -= read_bytes; + minchars -= read_bytes; + debug_printf ("vtime_ %u, vmin_ %u, read_bytes %u, tot %D", + vtime_, vmin_, read_bytes, tot); + } continue; err: