in reply to Builtin Watchdog for a sub (or block)

sub cheatemall { my $givetime = shift; my $curtime = time(); my $oldalarm; my $oldsig = $SIG{ALRM}; $SIG{ALRM} = die ( 'ALARM' ); eval { $oldalarm = alarm( $givetime ); alarm( $oldalarm ) if ( $oldalarm < $givetime ); if ( ... ) { ## Apply your logic here. &reset_old_alarm( $curtime, $oldalarm ); return ...; ## return X } else { &reset_old_alarm( $curtime, $oldalarm ); return ...; ## return Y } }; ## We must have died out to get here. if ( $@ =~ /OLD ALARM/ ) { ## We got caught on a parent alarm. Re-create that ## alarm outside of our local eval block. kill( 'ALRM', $$); } elsif ( $@ =~ /ALARM/ ) { ## We alarmed out locally. return ...; ## return Y } else { ## Died for some other reason.. handle it here. } } sub reset_old_alarm { ## If you want to do object oriented stuff, you could ## make this be sub DESTROY so that this logic happens ## whenever your watchdog object goes out of scope. my ($curtime, $oldalarm) = @_; return alarm(0) if ( $oldalarm == 0); $oldalarm -= ( time() - $curtime ); die ( 'OLD ALARM' ) if ( $oldalarm <= 0 ); alarm($oldalarm); }

UPDATE Fixed missing semicolon, thanx to Fatvamp

Replies are listed 'Best First'.
Re: Re: Builtin Watchdog for a sub (or block)
by osfameron (Hermit) on Apr 28, 2002 at 16:02 UTC
    alarm isn't (yet?) implemented on Win32. I'd argue that therefore this isn't a generic Perl solution, as it seems to be using OS specific functionality.
    (But I may be missing the point...)

    Cheerio!
    Osfameron
    http://osfameron.perlmonk.org/chickenman

      alarm isn't (yet?) implemented on Win32
      true. you can use Win32::Event, but the implementation's a little bit different than alarm.

      ~Particle *accelerates*

      I've posted a question on Ask Perl 6 on Use Perl about this: I think that it's wrong to call alarm and fork etc. features of the Perl language, because they are un- or partially- implemented for major platforms like Win32, and I'm hoping that Perl 6 will improve that!

      Cheerio!
      Osfameron
      http://osfameron.perlmonk.org/chickenman

        While Parrot may make some of that pain easier to deal with (alarm, for example, though it's got issues anyway once you're running with threads) I don't think you're going to see fork or alarm or whatever go away, and honestly I don't think they should. (And my platform of choice--VMS--doesn't fork, amongst other things)

        It's kind of silly to neuter things so you get a lowest-common-denominator system. Making perl platform independent by taking things away just hurts the people who're on platforms where it does work. (And fork is really unlikely to be completely emulated on Windows, or any other non-unix platform)

Re: Re: Builtin Watchdog for a sub (or block)
by PetaMem (Priest) on Apr 28, 2002 at 18:02 UTC
    Yes - basically this goes to the right direction. However I had some problems with the code and am not able to solve them all.
    • I guess theres a ; missing after the eval block
    • It would be nice to have finer granularity than 1 sec. probably Timer::HiRes can do here something.
    • I wasn't able to find out what return value alarm has... somehow the code always boils out with an alarm.
    • Quite frankly - I don't understand the "parent alarm" thing.

    Bye
     PetaMem

      I guess theres a ; missing after the eval block

      Yes, thank you.

      Quite frankly - I don't understand the "parent alarm" thing.

      This was my answer to your request for an algorithm that could recursively call itself. Say $oldalarm is 3 and $givetime is 20. Even though cheatmail may have 20 seconds to complete its task, you know that somewhere higher in the callstack, you have another watchdog (which I refer to as a 'parent') that is expecting to be done one way or another in 3 seconds. Using this algorithm, you know that whichever watchdog is expecting to be done in 3 seconds will be the one to receive the alarm signal.

      • It would be nice to have finer granularity than 1 sec. probably Timer::HiRes can do here something.
      it's Time::HiRes (not Timer::HiRes.) if you don't want to add the overhead of a module, you can use select, as in select('','','',$time); instead.

      ~Particle *accelerates*