perllearner has asked for the wisdom of the Perl Monks concerning the following question:

i have a test script that i use for getting feedback from a display controller... to basically check for buffer high or buffer low (which is preset) while testing the display. i am using sysread to do this. however sysread may hang if neither of the two cases are true for the controller. i want to incorporate a timeout so that the code skips and continues to send data to the display.
$buffer_high = 255; $buffer_low = 254; sub process_lcd { ... my $key = sysread (DisplayIO, $lcdValue, 1); return $lcdValue; } # end process_lcd # code then compares values for $lcdValue with $buffer_high and $buffe +r_low
the code hangs indefinitely at sysread. i wish to put a 1/500th sec timeout around the sysread.. thanks for your help in advance..

Replies are listed 'Best First'.
Re: exiting sysread if no input
by borisz (Canon) on Jun 15, 2004 at 17:07 UTC
    Use select to watch if some data is present. perldoc -f select
    Boris
Re: exiting sysread if no input
by Somni (Friar) on Jun 16, 2004 at 06:51 UTC

    There are a wide variety of methods for doing this. What follows is a brief rundown of things that may be relevant, with links to further information. Note, a timeout of hundredths of a second probably will not be possible, you are better off with a non-blocking read in that case.

    • select (see select); this will block as well, unless you provide a timeout. The timeout you provide can be sub-second, but usually the lowest it'll go is tenths of a second.
    • non-blocking read; the simplest way of making a handle non-blocking is to call the blocking method of IO::Handle. Fcntl will also allow you to do it (first, F_GETFL, then 'or' that with O_NONBLOCK, then F_SETFL). IO::Handle will probably be more portable.
    • alarm; set an alarm, set $SIG{ALRM} to die, and wrap your sysread in an eval. perlipc covers this in greater detail. The resolution is at a second, unless you use Time::HiRes, which will give you (possibly) microsecond resolution. Along the same vein is Time::HiRes::setitimer.
    • use POE, Event, stem, etc.; these are all examples of event loops; the resolution you get on timeouts depends on which you choose and how you go about things. It sounds like you're doing work in between checking this filehandle, and an event loop will do that while abstracting away a lot of the tedious work involved, so you can get right down to what you want to do.

    Also, consider getting your hands on the Unix Network Programming series, and Advanced Programming in the Unix Environment, all by W. Richard Stevens. They are excellent books, probably the most valuable in my library.