Calling alarm more than once

Discussion in 'Perl Misc' started by iulukus@gmail.com, May 18, 2007.

  1. Guest

    Hi,
    Is it possible to call the alarm more than once. If it is posible,
    how?
    I couldn't do it in my program:

    {
    ......
    ......
    RETRY:print "Send REQUEST to $server\n";

    $payload = "x87\x00\x0c\x02\x1b\x62\x1f\x73\x96\x40\x68\x74\xfb\xff
    \xff";

    $lpayload = length($payload);
    $dummy = syswrite($remote, $payload, $lpayload); # $remote is my UDP
    socket.
    print "Send REQUEST \n";

    eval {
    local $SIG{'ALRM'} = sub {print "abc";die "alarm\n"};
    alarm 6;
    sysread($remote, $result, 1024); # Read from socket
    alarm 0;
    };
    if ($@) {
    die unless $@ eq "alarm\n"; # propagate unexpected errors
    goto RETRY;
    # timed out
    }
    else {
    print $@;
    # didn't
    }

    OUTPUT:
    Send REQUEST to 1.1.1.1
    Send REQUEST
    abcalarm
    Send REQUEST to 1.1.1.1
    Send REQUEST


    For the second loop, program did not call the alarm subroutine and
    program hang.
    What can be the problem?
    thanks in advance.
    , May 18, 2007
    #1
    1. Advertising

  2. wrote:

    > Hi,
    > Is it possible to call the alarm more than once. If it is posible,
    > how?


    Assuming you are doing this on a typical unix system...

    No, unfortunately:

    man -S2 alarm

    ....
    DESCRIPTION
    alarm() arranges for a SIGALRM signal to be delivered to the process
    in seconds seconds.

    If seconds is zero, no new alarm() is scheduled.

    In any event any previously set alarm() is cancelled.
    ....

    > I couldn't do it in my program:


    No, but that's not an error. PITA, but expected.

    I didn't have time to read your code, but in order to run multiple pending
    alarms, one solution is to write your own multi-alarm
    subroutine/module/class, which queues alarm requests. That class then uses
    alarm() to time out to the next alarm scheduled to trip and does a callback
    to a user supplied subroutine, after setting up the next alarm().

    Beware of sleep() - that uses the same timer as alarm() so you may need to
    emulate that. Also beware of random other modules that use alarm() or
    sleep() internally.

    As usual, someone already had this problem before you and CPAN to the
    rescue:

    http://search.cpan.org/~johnsca/libalarm-1.0/lib/Alarm/Queued.pm

    Is that any use to you?

    HTH

    Tim
    Tim Southerwood, May 18, 2007
    #2
    1. Advertising

  3. Peter Scott Guest

    On Fri, 18 May 2007 10:04:23 +0100, Tim Southerwood wrote:
    > wrote:
    >
    >> Hi,
    >> Is it possible to call the alarm more than once. If it is posible,
    >> how?

    >
    > Assuming you are doing this on a typical unix system...
    >
    > No, unfortunately:
    >
    > man -S2 alarm


    Or on any system that Perl implements alarm():

    perldoc -f alarm
    [...]
    Only one timer may be counting at once. Each call disables the
    previous timer, and an argument of 0 may be supplied to cancel
    the previous timer without starting a new one. The returned
    value is the amount of time remaining on the previous timer.

    --
    Peter Scott
    http://www.perlmedic.com/
    http://www.perldebugged.com/
    Peter Scott, May 18, 2007
    #3
  4. Guest

    wrote:
    > Hi,
    > Is it possible to call the alarm more than once.


    Yes, but you can't have them nested.

    > If it is posible,
    > how?


    Just do it.



    > I couldn't do it in my program:
    >
    > {
    > .....
    > .....
    > RETRY:print "Send REQUEST to $server\n";
    >
    > $payload = "x87\x00\x0c\x02\x1b\x62\x1f\x73\x96\x40\x68\x74\xfb\xff
    > \xff";
    >
    > $lpayload = length($payload);
    > $dummy = syswrite($remote, $payload, $lpayload); # $remote is my UDP
    > socket.


    I don't have access to your UDP socket. So I took that part of your
    code out, and turned the sysread into a sleep 20. It worked as I expected,
    retrying repeatedly.



    > print "Send REQUEST \n";
    >
    > eval {
    > local $SIG{'ALRM'} = sub {print "abc";die "alarm\n"};
    > alarm 6;
    > sysread($remote, $result, 1024); # Read from socket
    > alarm 0;
    > };
    > if ($@) {
    > die unless $@ eq "alarm\n"; # propagate unexpected errors
    > goto RETRY;
    > # timed out
    > }
    > else {
    > print $@;


    What is the point of printing $@ when $@ is false?

    Perhaps the die-eval is screwing up your socket. If you include an
    simplified example for your UDP server, I'd give it a try and see what
    happens on my system.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
    , May 18, 2007
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jabba Laci
    Replies:
    0
    Views:
    293
    Jabba Laci
    Jan 24, 2012
  2. Red Ogden
    Replies:
    1
    Views:
    80
    Dom Leonard
    Jul 23, 2003
  3. Gancy
    Replies:
    4
    Views:
    176
    Rasto Levrinc
    Feb 3, 2005
  4. Steven D'Aprano
    Replies:
    0
    Views:
    90
    Steven D'Aprano
    Dec 23, 2013
  5. Replies:
    3
    Views:
    82
    Gary Herron
    Dec 23, 2013
Loading...

Share This Page