Async-Interrupt
view release on metacpan or search on metacpan
function has the following prototype and needs to be passed the
specified $signal_arg, which is a "void *" cast to "IV":
void (*signal_func) (void *signal_arg, int value)
An example call would look like:
signal_func (signal_arg, 0);
The function is safe to call from within signal and thread contexts,
at any time. The specified "value" is passed to both C and Perl
callback.
$value must be in the valid range for a "sig_atomic_t", except 0
(1..127 is portable).
If the function is called while the Async::Interrupt object is
already signaled but before the callbacks are being executed, then
the stored "value" is either the old or the new one. Due to the
asynchronous nature of the code, the "value" can even be passed to
two consecutive invocations of the callback.
$address = $async->c_var
Returns the address (cast to IV) of an "IV" variable. The variable
is set to 0 initially and gets set to the passed value whenever the
object gets signalled, and reset to 0 once the interrupt has been
handled.
Note that it is often beneficial to just call "PERL_ASYNC_CHECK ()"
to handle any interrupts.
Example: call some XS function to store the address, then show C
code waiting for it.
my_xs_func $async->c_var;
static IV *valuep;
void
my_xs_func (void *addr)
CODE:
valuep = (IV *)addr;
// code in a loop, waiting
while (!*valuep)
; // do something
$async->signal ($value=1)
This signals the given async object from Perl code. Semi-obviously,
this will instantly trigger the callback invocation (it does not, as
the name might imply, do anything with POSIX signals).
$value must be in the valid range for a "sig_atomic_t", except 0
(1..127 is portable).
$async->handle
Calls the callback if the object is pending.
This method does not need to be called normally, as it will be
invoked automatically. However, it can be used to force handling of
outstanding interrupts while the object is blocked.
One reason why one might want to do that is when you want to switch
from asynchronous interruptions to synchronous one, using e.g. an
event loop. To do that, one would first "$async->block" the
interrupt object, then register a read watcher on the "pipe_fileno"
that calls "$async->handle".
This disables asynchronous interruptions, but ensures that
interrupts are handled by the event loop.
$async->signal_hysteresis ($enable)
Enables or disables signal hysteresis (default: disabled). If a
POSIX signal is used as a signal source for the interrupt object,
then enabling signal hysteresis causes Async::Interrupt to reset the
signal action to "SIG_IGN" in the signal handler and restore it just
before handling the interruption.
When you expect a lot of signals (e.g. when using SIGIO), then
enabling signal hysteresis can reduce the number of handler
invocations considerably, at the cost of two extra syscalls.
Note that setting the signal to "SIG_IGN" can have unintended side
effects when you fork and exec other programs, as often they do not
expect signals to be ignored by default.
$async->block
$async->unblock
Sometimes you need a "critical section" of code that will not be
interrupted by an Async::Interrupt. This can be implemented by
calling "$async->block" before the critical section, and
"$async->unblock" afterwards.
Note that there must be exactly one call of "unblock" for every
previous call to "block" (i.e. calls can nest).
Since ensuring this in the presence of exceptions and threads is
usually more difficult than you imagine, I recommend using
"$async->scoped_block" instead.
$async->scope_block
This call "$async->block" and installs a handler that is called when
the current scope is exited (via an exception, by canceling the Coro
thread, by calling last/goto etc.).
This is the recommended (and fastest) way to implement critical
sections.
($block_func, $block_arg) = $async->scope_block_func
Returns the address of a function that implements the "scope_block"
functionality.
It has the following prototype and needs to be passed the specified
$block_arg, which is a "void *" cast to "IV":
void (*block_func) (void *block_arg)
An example call would look like:
block_func (block_arg);
( run in 2.535 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )