NAME
Linux::Event::Wakeup - subclass-defined eventfd wakeups
SYNOPSIS
use threads;
use Thread::Queue;
package LE::ResultsReady;
use parent 'Linux::Event::Wakeup';
sub on_wakeup ($wakeup, $count) {
my $queue = $wakeup->data;
while (defined(my $result = $queue->dequeue_nb)) {
say "worker produced $result";
}
$wakeup->loop->stop;
}
package main;
my $results = Thread::Queue->new;
my $wakeup = $loop->add(LE::ResultsReady->new(
data => $results, # optional
));
my $worker = threads->create(sub {
$results->enqueue('complete');
$wakeup->signal;
return 1;
});
$worker->join;
$loop->run;
DESCRIPTION
Wakeup is the public eventfd notification boundary for Linux::Event. A concrete subclass defines one named on_wakeup method. Calling signal increments the eventfd counter, wakes the owning Loop, and causes the Loop thread to invoke that method with the coalesced count.
Wakeup carries notification, not arbitrary Perl values. A producer that has results to deliver must store them in an appropriate thread-safe queue, shared memory region, pipe, socket, or other IPC mechanism before signalling. This keeps Perl coderefs and interpreter-owned values out of foreign threads.
Wakeup is not a general $loop->post($coderef) queue. Native resolver workers already use a private typed completion queue and eventfd. Wakeup is the public primitive for an application that has its own safe data channel and needs only to make the Loop notice it. Using raw $loop->watch directly would expose eventfd creation, counter draining, ownership, and clone rules at every call site; Wakeup centralizes those rules in one logical object.
DEFINING A WAKEUP TYPE
sub on_wakeup ($wakeup, $count) {
$wakeup->data->{total} += $count;
}
The callback CV is resolved once per subclass. $count is the eventfd total observed in one drain. Several signals may therefore produce one callback.
CONSTRUCTION
my $wakeup = LE::ResultsReady->new(
loop => $loop, # optional: attach immediately
data => $data, # optional
);
The base class is abstract. Supply loop or construct the Wakeup detached and attach it with $loop->add($wakeup). A Wakeup attaches once and cannot be reused after cancellation.
METHODS
signal($increment = 1)
Atomically adds a positive integer to the eventfd counter and returns the Wakeup. The implementation performs only an XS eventfd write after validating the scalar argument. The maximum is the smaller of the eventfd counter range and Perl's native unsigned-integer range. It never invokes on_wakeup inline.
A cloned handle on a threaded Perl build may call signal. Each interpreter clone owns a close-on-exec duplicate of the eventfd descriptor, so cancellation in the Loop interpreter cannot turn a stale descriptor number into an unrelated write. That duplicate is valid only in the interpreter that received it; an object accidentally returned through join cannot manage the owner or reuse the worker's closed descriptor. A child created after Wakeup construction may call signal before it executes another program. Neither case permits the foreign interpreter or child to attach, cancel, or change application data.
cancel
Idempotently removes the Loop registration, closes the eventfd, releases data, and makes the Wakeup terminal. Only the creating interpreter may cancel it.
data([$value])
Gets or replaces the application value in the creating interpreter.
loop
Returns the owning Loop while active, otherwise undef.
state
Returns unattached, active, or cancelled.
is_active / is_terminal
Report the current lifecycle category.
THREAD AND PROCESS BOUNDARY
Linux::Event itself does not require a threaded Perl. Native library workers may signal eventfds without entering Perl. On a Perl built with ithreads, a worker interpreter receives cloned Perl values; it does not share callbacks or ordinary data with the Loop interpreter. Wakeup deliberately transfers only the counter increment.
After fork, the child inherits the eventfd and may wake the parent until it executes another program. The eventfd is close-on-exec. It does not transport a payload; cross-process data still requires IPC.
CALLBACK EXCEPTIONS
An exception from on_wakeup propagates out of Loop dispatch. It does not implicitly cancel the Wakeup.