http://qs321.pair.com?node_id=859287

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

I'm using following code:
$inotify->watch ($watchdir, IN_ALL_EVENTS) or die "watch creat +ion failed" ; $0="cping: watch ready, waiting for activity (".scalar(localti +me()).")..."; my @events = $inotify->read;
the line $inotify->read; is blocking, which is nice, since it doesn't burn CPU when there is nothing to do. But, now I need to run code, when there was no activity for longer then $timelimit; I could switch to non-blocking calls, ie use something like this:
$inotify->blocking(0); ... $inotify->read; sleep 1s; if ($idle>$timelimit) { code(); };
but then my code starts burning CPU AND becomes less responsive ( blocking code has much better then a 1 second latency with reacting to activity in $watchdir ). Is there any way out?

Replies are listed 'Best First'.
Re: Blocking call with time limit ( Linux::Inotify2 )
by BrowserUk (Patriarch) on Sep 08, 2010 at 09:03 UTC

    The simple solution is Time::HiRes:

    use Time::HiRes qw[ time sleep ]; ... $inotify->blocking(0); my $end = time() + $timelimit; while( time() < $end ) { for my $event ( $inotify->read ) { ## process event. } sleep 0.01; ## or 0.001 per your latency requirements }

    As for your fears about cpu usage. Polling once every hundredth or thousandth of a second, (much less every second), barely raises the usage at all. On my system, the usage is not discernible from zero to 2 decimal places.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Blocking call with time limit ( Linux::Inotify2 )
by Corion (Patriarch) on Sep 08, 2010 at 08:56 UTC

    I'm not sure whether the API for Linux::Inotify2 allows for a timeout.

    Before entering into the melee of signals or threads, I would look at the AnyEvent integration of Linux::Inotify2, maybe AnyEvent::Filesys::Notify. Using something like AnyEvent will turn parts of your program inside out, as you will get callbacks instead of actively check on things yourself.