Trying to interrupt a blocking read...

Benjamin Ellsworth 2GigSpamBucket at gmail.com
Fri Sep 13 00:33:29 UTC 2019


It appears that VTIME does not work.  I set both VMIN and VTIME and I 
never get a timeout.  The read continues to happily block forever.

Also, when looking at VTIME handling down in the code, I see in 
termios.c the function fillBufferPoll().  It looks to me like that 
function expects (*tty->handler.poll_read) to return in less than 
tty->vtimeTicks in every case.  I don't see how that is guaranteed.

If (*tty->handler.poll_read) blocks until a byte shows up, then VTIME is 
basically meaningless.  I don't see any code that sends VTIME or 
vtimeTicks down to the underlying handler, so I don't see how the 
timeout could possibly be honored.

Or maybe there's something I don't understand...


Here is the function:

static void
fillBufferPoll (struct rtems_termios_tty *tty)
{
   int n;

   if (tty->termios.c_lflag & ICANON) {
     for (;;) {
       n = (*tty->handler.poll_read)(tty->device_context);
       if (n < 0) {
         rtems_task_wake_after (1);
       } else {
         if  (siprocPoll (n, tty))
           break;
       }
     }
   } else {
     rtems_interval then, now;

     then = rtems_clock_get_ticks_since_boot();
     for (;;) {
       n = (*tty->handler.poll_read)(tty->device_context);
       if (n < 0) {
         if (tty->termios.c_cc[VMIN]) {
           if (tty->termios.c_cc[VTIME] && tty->ccount) {
             now = rtems_clock_get_ticks_since_boot();
             if ((now - then) > tty->vtimeTicks) {
               break;
             }
           }
         } else {
           if (!tty->termios.c_cc[VTIME])
             break;
           now = rtems_clock_get_ticks_since_boot();
           if ((now - then) > tty->vtimeTicks) {
             break;
           }
         }
         rtems_task_wake_after (1);
       } else {
         siprocPoll (n, tty);
         if (tty->ccount >= tty->termios.c_cc[VMIN])
           break;
         if (tty->termios.c_cc[VMIN] && tty->termios.c_cc[VTIME])
           then = rtems_clock_get_ticks_since_boot();
       }
     }
   }
}


Or, maybe there's something I don't understand...

Thanks.



On 10-Sep-19 10:18 AM, Joel Sherrill wrote:
> On Tue, Sep 10, 2019 at 12:09 AM Benjamin Ellsworth
> <2gigspambucket at gmail.com> wrote:
>>
>> Hello,
>>
>> The code I'm working with currently does a read() on a device that has
>> been opened with an open() call (a UART if that matters).  It nicely
>> blocks waiting for a character (potentially forever).
>>
>> I now need that read to be interrupted...  I looked for pselect() so it
>> can block until I tell it to stop (via signal from another thread), but
>> that doesn't seem to be supported.  I looked at the classic work-around
>> using a pipe in a select call, but pipe() isn't supported and select
>> apparently only works on sockets (and the comments in the select header
>> make it sound like even that is a bad idea).
>
> What version? I thought select() on termios devices was added at least
> to the master.
>
> You are right that it historically hasn't worked.
>
> pipe() is supported. psxpipe01 is the test. Not sure about the use case
> you have in mind.
>
>> I can probably make things work with timeouts--basically making it into
>> a polling loop, but I can't see a way to make the read timeout.  I dug
>> down into the rtems read functions, but didn't see any way to make them
>> timeout, nor did I see a way to cleanly interrupt them.
>
> read() on a UART should be able to do non-blocking or timeout on read()
> with the VMIN and VTIME support from termios. There should be examples
> of this around the net.
>
>> If anyone has any suggestions/ideas/pointers, I'd appreciate them.
>
> --joel
>>
>>
>> Thanks.
>>
>> _______________________________________________
>> devel mailing list
>> devel at rtems.org
>> http://lists.rtems.org/mailman/listinfo/devel
>




More information about the devel mailing list