EOF on a watched handle

[email protected] ((Jochen Stenzel))
Newsgroups perl.loop
Message-ID <005a01bf8df9$6f3ff9a0$8591b8d4@jochen>
Hello,

the following code is the main part of an example prepared for the workshop, emulating "tail -f":

- snip --

# install "tail -f"
Event->io(
          fd=>\*IN,
          cb=>sub {
                   # check for real news
                   return if eof(IN);

                   # read new line and report it
                   print "New line detected: ", scalar(<IN>), "\n";
                  }
         );

- snip ---

Please note the lines

- snip ---

 # check for real news
 return if eof(IN);

- snip ---

which I had to add because an event occurs even if nothing new arrives in the file. Well, this was ok for me in a demonstration focussed on an io watcher, but now someone asked me if there is a way to avoid callback invokation for EOF. Running the script again, I recognized that it enforces a very high load.

Ok, I suppose this is because of the underlaying select() call. I read the manpage of IO::Select which mentions EOF as an ERROR (to be detected by has_error()), not a "ready to be read" event (checked by can_read()). Nevertheless, even with IO::Select and usage of can_read() EOF is detected as an event as well:

- snip --

use IO::Select;

$s=IO::Select->new;

open(IN, "tailtest.tmp");
$s->add(\*IN);

while ($s->can_read(0))
 {
  next if $s->has_error(0);
  print "New line detected: ", scalar(<IN>), "\n";
 }

- snip --

This surely is a basic problem. The question is if there is a solution? What I'm looking for is to get a read event (poll=>'r') ONLY if there is something to read, not in case of EOF (which could be matched by poll=>'e'). Ideally, this solution would result in a lower load than the example above.

                        Jochen
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.