NAME
Linux::Event::Listen - Listening sockets for Linux::Event
SYNOPSIS
use v5.36;
use Linux::Event;
use Linux::Event::Listen;
my $loop = Linux::Event->new;
my $listen = Linux::Event::Listen->new(
loop => $loop,
host => '127.0.0.1',
port => 3000,
on_accept => sub ($loop, $client_fh, $peer, $listen) {
# You own $client_fh. It is already non-blocking.
# Attach whatever per-connection watchers you want:
$loop->watch($client_fh,
read => sub ($loop, $fh, $w) {
my $buf;
my $n = sysread($fh, $buf, 8192);
if (!defined $n || $n == 0) {
$w->cancel;
close $fh;
return;
}
# ... handle $buf ...
},
);
},
on_error => sub ($loop, $err, $listen) {
warn "listener error ($err->{op}): $err->{error}\n";
},
);
$loop->run;
DESCRIPTION
Linux::Event::Listen creates or wraps a listening socket and attaches it to a Linux::Event loop. When the socket becomes readable, it accepts connections and invokes your on_accept callback once per accepted client.
This distribution is intentionally small and policy-light:
It does not create per-connection watchers for you.
It guarantees the correct accept-drain behavior required for edge-triggered notification (accept until
EAGAIN), with a fairness cap.
CONSTRUCTOR
new
my $listen = Linux::Event::Listen->new(%args);
Required:
loopA Linux::Event::Loop instance.
on_accepton_accept => sub ($loop, $client_fh, $peer, $listen) { ... }Called once per accepted connection.
You must also provide either:
fhA listening socket handle (already bound and in listen state), or
hostandportTCP address to bind and listen on, or
pathUNIX domain socket path to bind and listen on.
OPTIONS
on_accept
on_accept => sub ($loop, $client_fh, $peer, $listen) { ... }
Your callback is invoked once per accepted connection.
Ownership: you own $client_fh. This module never closes it.
on_error
on_error => sub ($loop, $err, $listen) { ... }
on_emfile
on_emfile => sub ($loop, $err, $listen) { ... }
Optional callback invoked when accept() fails with EMFILE or ENFILE. This is where production servers often implement "reserve FD" mitigation.
Optional callback invoked for accept-time errors and watcher error/hup events.
$err is a hashref with keys like:
{ op => 'accept', errno => ..., error => "...", fatal => 0 }
edge_triggered
edge_triggered => 1 # default
Sets the underlying watcher to edge-triggered mode. The accept loop always drains the accept queue until EAGAIN, which is required for correctness when edge triggered.
oneshot
oneshot => 0 # default
Passed through to the underlying watcher.
max_accept_per_tick
max_accept_per_tick => 128 # default
Upper bound on accepted connections per readable event callback.
If you set this option without explicitly setting edge_triggered, this module will default to level-triggered readiness so the cap cannot stall the listener.
If you explicitly enable edge_triggered and also cap accepts-per-tick, you must ensure you still eventually drain accept() until EAGAIN (for example by using a level-triggered listener, or designing your own re-arm strategy).
cloexec
cloexec => 1 # default
Sets FD_CLOEXEC on the listening socket and accepted sockets (best-effort).
nonblocking
nonblocking => 1 # default
Accepted sockets are set non-blocking (best-effort). The listening socket is also set non-blocking.
path
path => '/tmp/app.sock'
Bind and listen on a UNIX domain socket path.
unlink
unlink => 1
If true and path is used, unlink the path before binding (useful for restarts).
unlink_on_cancel
unlink_on_cancel => 1
If true and path is used, unlink the socket file when the listener is cancelled (or destroyed). Defaults to true for internally-created UNIX sockets.
owns_socket
If true, $listen->cancel will close the listening socket. Defaults to false when fh is provided, and true when the socket is created internally.
METHODS
fh
my $fh = $listen->fh;
Return the listening socket handle.
fd
my $fd = $listen->fd;
sockhost / sockport
my $host = $listen->sockhost;
my $port = $listen->sockport;
Convenience accessors that delegate to the underlying socket handle. For UNIX sockets these may return undef, depending on the underlying implementation.
Return the numeric file descriptor of the listening socket (or undef).
watcher
my $w = $listen->watcher;
is_running
if ($listen->is_running) { ... }
True if the underlying watcher is installed.
Return the underlying Linux::Event::Watcher.
pause / resume
$listen->pause;
$listen->resume;
Disable/enable read interest on the listening socket.
cancel
$listen->cancel;
Cancel the underlying watcher and, if owns_socket is true, close the listening socket.
ERROR HASH
When on_error or on_emfile is invoked, the second argument is a hashref describing the condition.
Common keys:
op - one of: setup, accept, watch, on_accept
error - string form of the error
errno - numeric errno (only when the error came from C<$!>)
fatal - boolean (true for setup failures)
Depending on how the listener was created, host/port or path may be present for op = setup errors.
ACCEPT LOOP SEMANTICS
When the listening socket is readable, this module attempts to accept connections in a loop until one of these conditions is met:
accept returns
EAGAIN/EWOULDBLOCK(normal)max_accept_per_tickis reached (fairness)a non-retryable accept error occurs
The following errors are retried: EINTR, ECONNABORTED.
NOTES
SEE ALSO
Linux::Event, Linux::Event::Loop, Linux::Event::Watcher, IO::Socket::IP
AUTHOR
Joshua S. Day
LICENSE
Same terms as Perl itself.