Alarm::Queued - Allow multiple, queued alarms.
This module is an attempt to enhance Perl's built-in
alarm/$SIG{ALRM} functionality.
The built-in function, and its associated signal handler, allow
you to arrange for your program to receive a SIGALRM signal, which you can
then catch and deal with appropriately.
Unfortunately, due to the nature of the design of these signals
(at the OS level), you can only have one alarm and handler active at any
given time. That's where this module comes in.
This module allows you to define multiple alarms, each with an
associated handler. These alarms are queued, which means that if you set one
alarm and then set another alarm, shorter than the first, the second alarm
does not go off until after the first one has gone off and been handled. (If
you'd like to have the alarms go off as their set time expires, regardless
of whether or not previous alarms are still pending, see
Alarm::Concurrent.)
To set an alarm, call the
"setalarm()" function with the set time of
the alarm and a reference to the subroutine to be called when the alarm goes
off. You can then go on with your program and the alarm will be called after
the set time has passed.
It is also possible to set an alarm that does not have a handler
associated with it using
"Alarm::Queued::alarm()". (This function
can also be imported into your namespace, in which case it will replace
Perl's built-in alarm for your package only.)
If an alarm that does not have a handler associated with it goes
off, the default handler, pointed to by
$Alarm::Queued::DEFAULT_HANLDER, is called. You can
change the default handler by assigning to this variable.
The default
$Alarm::Queued::DEFAULT_HANDLER simply dies with the
message "Alarm clock!\n".
No methods are exported by default but you can import any of the functions in
the FUNCTIONS section.
You can also import the special tag
":ALL" which will import all the functions
in the FUNCTIONS section.
If you import the special tag ":OVERRIDE",
this module will override Perl's built-in alarm function for every
namespace and it will take over Perl's magic %SIG
variable, changing any attempts to read or write
$SIG{ALRM} into calls to
"gethandler()" and
"sethandler()", respectively.
This can be useful when you are calling code that tries to set its
own alarm the "old fashioned way." It can also, however, be
dangerous. Overriding alarm is documented and should be stable but taking
over %SIG is more risky (see CAVEATS).
Note that if you do not override alarm and
%SIG, any code you use that sets "legacy
alarms" will disable all of your queued alarms. You can call
"Alarm::Queued::restore()" to reinstall
the Alarm::Queued handler. This function may not be imported.
The following functions are available for use.
- setalarm SECONDS CODEREF
- Sets a new alarm and associates a handler with it. This handler is called
when the specified number of seconds have elapsed and all previous
alarms have gone off. See DESCRIPTION for more information.
- clearalarm INDEX LENGTH
- clearalarm INDEX
- clearalarm
- Clears one or more previously set alarms. The index is an array index,
with 0 being the currently active alarm and -1 being the last (most
recent) alarm that was set.
INDEX defaults to 0 and LENGTH defaults to 1.
If you clear the active alarm and it was blocking other alarms
from going off, those alarms are immediately triggered.
- alarm SECONDS
- alarm
- Creates a new alarm with no handler. A handler can later be set for it via
sethandler() or $SIG{ALRM}, if overridden.
For the most part, this function behaves exactly like Perl's
built-in alarm function, except that it sets up a concurrent alarm
instead. Thus, each call to alarm does not disable previous alarms
unless called with a set time of 0.
Calling "alarm()" with a set
time of 0 will disable the last alarm set.
If SECONDS is not specified, the value stored in
$_ is used.
- sethandler INDEX CODEREF
- sethandler CODEREF
- Sets a handler for the alarm found at INDEX in the queue. This is an array
index, so negative values may be used to indicate a position relative to
the end of the queue.
If INDEX is not specified, the handler is set for the last
alarm in the queue that doesn't have one associated with it. This means
that if you set multiple alarms using
"alarm()", you should arrange their
respective "sethandler()"'s in the
opposite order.
- gethandler INDEX
- gethandler
- Returns the handler for the alarm found at INDEX in the queue. This is an
array index, so negative values may be used.
If INDEX is not specified, returns the handler for the
currently active alarm.
- restore FLAG
- restore
- This function reinstalls the Alarm::Queued alarm handler if it has been
replaced by a "legacy alarm handler."
If FLAG is present and true,
"restore()" will save the current
handler by setting it as a new queued alarm (as if you had called
"setalarm()" for it).
This function may not be imported.
Note: Do not call this function if you have imported
the ":OVERLOAD" symbol. It can have
unpredictable results.
- %SIG is Perl magic and should probably not be
messed with, though I have not witnessed any problems in the (admittedly
limited) testing I've done. I would be interested to hear from anyone who
performs extensive testing, with different versions of Perl, of the
reliability of doing this.
Moreover, since there is no way to just take over
$SIG{ALRM}, the entire magic hash is usurped and
any other "%SIG}" accesses are simply
passed through to the original magic hash. This means that if there
are any problems, they will most likely affect all other signal
handlers you have defined, including
$SIG{__WARN__} and
$SIG{__DIE__} and others.
In other words, if you're going to use the :OVERRIDE option,
you do so at your own risk (and you'd better be pretty damn sure of
yourself, too).
- The default $DEFAULT_HANDLER simply dies with the
message "Alarm clock!\n".
- All warnings about alarms possibly being off by up to a full second still
apply. See the documentation for alarm for more information.
- The alarm handling routine does not make any allowances for systems that
clear the alarm handler before it is called. This may be changed in the
future.
- According to "Signals" in perlipc, doing just about
anything in signal handling routines is dangerous because it might
be called during a non-re-entrant system library routines which could
cause a memory fault and core dump.
The Alarm::Queued alarm handling routine does quite a bit.
You have been warned.
Written by Cory Johns (c) 2001.
Hey! The above document had some coding errors, which are explained
below:
- Around line 346:
- You forgot a '=back' before '=head1'