Setting termios VMIN > 0 and VTIME > 0 on non blocking file
Åke Rehnman
ake.rehnman@gmail.com
Thu Mar 12 17:04:05 GMT 2020
On 2020-03-12 16:08, Corinna Vinschen wrote:
> On Mar 12 15:44, Corinna Vinschen wrote:
>> On Mar 12 15:20, Åke Rehnman via Cygwin wrote:
>>> I think the problem is if the number of bytes requested are more than what
>> To clarify: number of bytes == VMIN?
no number of bytes requested from ReadFile(). As far as I know Win32 has
no concept of VMIN.
>>
>>> is in the buffer it is going to overlap the read function (because of VTIME)
>>> and immediately after that CancelIO is called. Contrary to what is mentioned
>>> in the source code I think CancelIO is actually discarding data...
>> So far we didn't have that experience. CancelIO is usually safe
>> in this regard.
The data is MIA somehow...
>>
>>> /* Use CancelIo rather than PurgeComm (PURGE_RXABORT) since
>>> PurgeComm apparently discards in-flight bytes while CancelIo
>>> only stops the overlapped IO routine. */
>>>
>>>
>>> My suggestion is the following patch:
>>>
>>> diff --git a/winsup/cygwin/fhandler_serial.cc
>>> b/winsup/cygwin/fhandler_serial.cc
>>> index 69e5768f6..afa8871bf 100644
>>> --- a/winsup/cygwin/fhandler_serial.cc
>>> +++ b/winsup/cygwin/fhandler_serial.cc
>>> @@ -898,7 +898,11 @@ fhandler_serial::tcsetattr (int action, const struct
>>> termios *t)
>>> {
>>> memset (&to, 0, sizeof (to));
>>>
>>> - if ((vmin_ > 0) && (vtime_ == 0))
>>> + if (is_nonblocking())
>>> + {
>>> + to.ReadIntervalTimeout = MAXDWORD;
>>> + }
>>> + else if ((vmin_ > 0) && (vtime_ == 0))
>> What if you switch to !O_NONBLOCK after calling tcsetattr? The
>> setting of ReadIntervalTimeout would be lost then.
>>
>> Either we have to repeat calling SetCommTimeouts every time
>> we switch mode, or we have to do the above setting temporary
>> every time we call ReadFile in non blocking mode.
True.
> What about this:
>
> diff --git a/winsup/cygwin/fhandler_serial.cc b/winsup/cygwin/fhandler_serial.cc
> --- a/winsup/cygwin/fhandler_serial.cc
> +++ b/winsup/cygwin/fhandler_serial.cc
> @@ -68,6 +68,16 @@ fhandler_serial::raw_read (void *ptr, size_t& ulen)
> goto err;
> else if (ev)
> termios_printf ("error detected %x", ev);
> + else if (is_nonblocking ())
> + {
> + if (!st.cbInQue)
> + {
> + tot = -1;
> + set_errno (EAGAIN);
> + goto out;
> + }
> + inq = st.cbInQue;
> + }
> else if (st.cbInQue && !vtime_)
> inq = st.cbInQue;
> else if (!is_nonblocking () && !overlapped_armed)
Looks promising. I will try it.
BTW there is a gremlin in the "else if (ev)" line....
/Ake
More information about the Cygwin
mailing list