Acme-Sort-Sleep
view release on metacpan or search on metacpan
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
format recognised by L<IO::Async::OS>'s C<extract_addrinfo> method.
This example shows how to use the C<Socket> functions to construct one for TCP
port 8001 on address 10.0.0.1:
$loop->connect(
addr => {
family => "inet",
socktype => "stream",
port => 8001,
ip => "10.0.0.1",
},
...
);
This example shows another way to connect to a UNIX socket at F<echo.sock>.
$loop->connect(
addr => {
family => "unix",
socktype => "stream",
path => "echo.sock",
},
...
);
=item local_addrs => ARRAY
=item local_addr => HASH or ARRAY
Optional. Similar to the C<addrs> or C<addr> parameters, these specify a local
address or set of addresses to C<bind(2)> the socket to before
C<connect(2)>ing it.
=back
When performing the resolution step too, the C<addrs> or C<addr> keys are
ignored, and instead the following keys are taken:
=over 8
=item host => STRING
=item service => STRING
The hostname and service name to connect to.
=item local_host => STRING
=item local_service => STRING
Optional. The hostname and/or service name to C<bind(2)> the socket to locally
before connecting to the peer.
=item family => INT
=item socktype => INT
=item protocol => INT
=item flags => INT
Optional. Other arguments to pass along with C<host> and C<service> to the
C<getaddrinfo> call.
=item socktype => STRING
Optionally may instead be one of the values C<'stream'>, C<'dgram'> or
C<'raw'> to stand for C<SOCK_STREAM>, C<SOCK_DGRAM> or C<SOCK_RAW>. This
utility is provided to allow the caller to avoid a separate C<use Socket> only
for importing these constants.
=back
It is necessary to pass the C<socktype> hint to the resolver when resolving
the host/service names into an address, as some OS's C<getaddrinfo> functions
require this hint. A warning is emitted if neither C<socktype> nor C<protocol>
hint is defined when performing a C<getaddrinfo> lookup. To avoid this warning
while still specifying no particular C<socktype> hint (perhaps to invoke some
OS-specific behaviour), pass C<0> as the C<socktype> value.
In either case, it also accepts the following arguments:
=over 8
=item handle => IO::Async::Handle
Optional. If given a L<IO::Async::Handle> object or a subclass (such as
L<IO::Async::Stream> or L<IO::Async::Socket> its handle will be set to the
newly-connected socket on success, and that handle used as the result of the
future instead.
=item on_fail => CODE
Optional. After an individual C<socket(2)> or C<connect(2)> syscall has failed,
this callback is invoked to inform of the error. It is passed the name of the
syscall that failed, the arguments that were passed to it, and the error it
generated. I.e.
$on_fail->( "socket", $family, $socktype, $protocol, $! );
$on_fail->( "bind", $sock, $address, $! );
$on_fail->( "connect", $sock, $address, $! );
Because of the "try all" nature when given a list of multiple addresses, this
callback may be invoked multiple times, even before an eventual success.
=back
This method accepts an C<extensions> parameter; see the C<EXTENSIONS> section
below.
=head2 connect (void)
$loop->connect( %params )
When not returning a future, additional parameters can be given containing the
continuations to invoke on success or failure.
=over 8
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
elsif( !defined wantarray and exists $params{host} || exists $params{local_host} ) {
croak "Expected 'on_resolve_error' callback or to return a Future";
}
my $connector = $self->{connector} ||= $self->__new_feature( "IO::Async::Internals::Connector" );
my $future = $connector->connect( %params );
$future = $future->then( sub {
$handle->set_handle( shift );
return Future->done( $handle )
}) if $handle;
$future->on_done( $on_done ) if $on_done;
$future->on_fail( sub {
$on_connect_error->( @_[2,3] ) if $on_connect_error and $_[1] eq "connect";
$on_resolve_error->( $_[2] ) if $on_resolve_error and $_[1] eq "resolve";
} );
return $future if defined wantarray;
# Caller is not going to keep hold of the Future, so we have to ensure it
# stays alive somehow
$future->on_ready( sub { undef $future } ); # intentional cycle
}
=head2 listen
$listener = $loop->listen( %params )->get
This method sets up a listening socket and arranges for an acceptor callback
to be invoked each time a new connection is accepted on the socket. Internally
it creates an instance of L<IO::Async::Listener> and adds it to the Loop if
not given one in the arguments.
Addresses may be given directly, or they may be looked up using the system's
name resolver, or a socket handle may be given directly.
If multiple addresses are given, or resolved from the service and hostname,
then each will be attempted in turn until one succeeds.
In named resolver mode, the C<%params> hash takes the following keys:
=over 8
=item service => STRING
The service name to listen on.
=item host => STRING
The hostname to listen on. Optional. Will listen on all addresses if not
supplied.
=item family => INT
=item socktype => INT
=item protocol => INT
=item flags => INT
Optional. Other arguments to pass along with C<host> and C<service> to the
C<getaddrinfo> call.
=item socktype => STRING
Optionally may instead be one of the values C<'stream'>, C<'dgram'> or
C<'raw'> to stand for C<SOCK_STREAM>, C<SOCK_DGRAM> or C<SOCK_RAW>. This
utility is provided to allow the caller to avoid a separate C<use Socket> only
for importing these constants.
=back
It is necessary to pass the C<socktype> hint to the resolver when resolving
the host/service names into an address, as some OS's C<getaddrinfo> functions
require this hint. A warning is emitted if neither C<socktype> nor C<protocol>
hint is defined when performing a C<getaddrinfo> lookup. To avoid this warning
while still specifying no particular C<socktype> hint (perhaps to invoke some
OS-specific behaviour), pass C<0> as the C<socktype> value.
In plain address mode, the C<%params> hash takes the following keys:
=over 8
=item addrs => ARRAY
Reference to an array of (possibly-multiple) address structures to attempt to
listen on. Each should be in the layout described for C<addr>. Such a layout
is returned by the C<getaddrinfo> named resolver.
=item addr => ARRAY
Shortcut for passing a single address to listen on; it may be passed directly
with this key, instead of in another array of its own. This should be in a
format recognised by L<IO::Async::OS>'s C<extract_addrinfo> method. See also
the C<EXAMPLES> section.
=back
In direct socket handle mode, the following keys are taken:
=over 8
=item handle => IO
The listening socket handle.
=back
In either case, the following keys are also taken:
=over 8
=item on_fail => CODE
Optional. A callback that is invoked if a syscall fails while attempting to
create a listening sockets. It is passed the name of the syscall that failed,
the arguments that were passed to it, and the error generated. I.e.
$on_fail->( "socket", $family, $socktype, $protocol, $! );
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
foreach my $addr ( @$addrs ) {
my ( $family, $socktype, $proto, $address ) = IO::Async::OS->extract_addrinfo( $addr );
my $sock;
unless( $sock = IO::Async::OS->socket( $family, $socktype, $proto ) ) {
$socketerr = $!;
$on_fail->( socket => $family, $socktype, $proto, $! ) if $on_fail;
next;
}
if( $reuseaddr ) {
unless( $sock->sockopt( SO_REUSEADDR, 1 ) ) {
$sockopterr = $!;
$on_fail->( sockopt => $sock, SO_REUSEADDR, 1, $! ) if $on_fail;
next;
}
}
if( defined $v6only and $family == AF_INET6 ) {
unless( $sock->setsockopt( IPPROTO_IPV6, IPV6_V6ONLY, $v6only ) ) {
$sockopterr = $!;
$on_fail->( sockopt => $sock, IPV6_V6ONLY, $v6only, $! ) if $on_fail;
next;
}
}
unless( $sock->bind( $address ) ) {
$binderr = $!;
$on_fail->( bind => $sock, $address, $! ) if $on_fail;
next;
}
unless( $sock->listen( $queuesize ) ) {
$listenerr = $!;
$on_fail->( listen => $sock, $queuesize, $! ) if $on_fail;
next;
}
return $self->_listen_handle( $listener, $sock, %params );
}
my $f = $self->new_future;
return $f->fail( "Cannot listen() - $listenerr", listen => listen => $listenerr ) if $listenerr;
return $f->fail( "Cannot bind() - $binderr", listen => bind => $binderr ) if $binderr;
return $f->fail( "Cannot setsockopt() - $sockopterr", listen => sockopt => $sockopterr ) if $sockopterr;
return $f->fail( "Cannot socket() - $socketerr", listen => socket => $socketerr ) if $socketerr;
die 'Oops; $loop->listen failed but no error cause was found';
}
sub _listen_hostservice
{
my $self = shift;
my ( $listener, $host, $service, %params ) = @_;
$host ||= "";
defined $service or $service = ""; # might be 0
my %gai_hints;
exists $params{$_} and $gai_hints{$_} = $params{$_} for qw( family socktype protocol flags );
defined $gai_hints{socktype} or defined $gai_hints{protocol} or
carp "Attempting to ->listen without either 'socktype' or 'protocol' hint is not portable";
$self->resolver->getaddrinfo(
host => $host,
service => $service,
passive => 1,
%gai_hints,
)->then( sub {
my @addrs = @_;
$self->_listen_addrs( $listener, \@addrs, %params );
});
}
=head1 OS ABSTRACTIONS
Because the Magic Constructor searches for OS-specific subclasses of the Loop,
several abstractions of OS services are provided, in case specific OSes need
to give different implementations on that OS.
=cut
=head2 signame2num
$signum = $loop->signame2num( $signame )
Legacy wrappers around L<IO::Async::OS> functions.
=cut
sub signame2num { shift; IO::Async::OS->signame2num( @_ ) }
=head2 time
$time = $loop->time
Returns the current UNIX time in fractional seconds. This is currently
equivalent to C<Time::HiRes::time> but provided here as a utility for
programs to obtain the time current used by L<IO::Async> for its own timing
purposes.
=cut
sub time
{
my $self = shift;
return Time::HiRes::time;
}
=head2 fork
$pid = $loop->fork( %params )
This method creates a new child process to run a given code block, returning
its process ID.
=over 8
=item code => CODE
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
required to implement certain methods that form the base level of
functionality. They are not recommended for applications to use; see instead
the various event objects or higher level methods listed above.
These methods should be considered as part of the interface contract required
to implement a C<IO::Async::Loop> subclass.
=cut
=head2 API_VERSION
IO::Async::Loop->API_VERSION
This method will be called by the magic constructor on the class before it is
constructed, to ensure that the specific implementation will support the
required API. This method should return the API version that the loop
implementation supports. The magic constructor will use that class, provided
it declares a version at least as new as the version documented here.
The current API version is C<0.49>.
This method may be implemented using C<constant>; e.g
use constant API_VERSION => '0.49';
=cut
=head2 watch_io
$loop->watch_io( %params )
This method installs callback functions which will be invoked when the given
IO handle becomes read- or write-ready.
The C<%params> hash takes the following keys:
=over 8
=item handle => IO
The IO handle to watch.
=item on_read_ready => CODE
Optional. A CODE reference to call when the handle becomes read-ready.
=item on_write_ready => CODE
Optional. A CODE reference to call when the handle becomes write-ready.
=back
There can only be one filehandle of any given fileno registered at any one
time. For any one filehandle, there can only be one read-readiness and/or one
write-readiness callback at any one time. Registering a new one will remove an
existing one of that type. It is not required that both are provided.
Applications should use a L<IO::Async::Handle> or L<IO::Async::Stream> instead
of using this method.
If the filehandle does not yet have the C<O_NONBLOCK> flag set, it will be
enabled by this method. This will ensure that any subsequent C<sysread>,
C<syswrite>, or similar will not block on the filehandle.
=cut
# This class specifically does NOT implement this method, so that subclasses
# are forced to. The constructor will be checking....
sub __watch_io
{
my $self = shift;
my %params = @_;
my $handle = delete $params{handle} or croak "Expected 'handle'";
defined eval { $handle->fileno } or croak "Expected that 'handle' has defined ->fileno";
# Silent "upgrade" to O_NONBLOCK
$handle->blocking and $handle->blocking(0);
my $watch = ( $self->{iowatches}->{$handle->fileno} ||= [] );
$watch->[0] = $handle;
if( exists $params{on_read_ready} ) {
$watch->[1] = delete $params{on_read_ready};
}
if( exists $params{on_write_ready} ) {
$watch->[2] = delete $params{on_write_ready};
}
if( exists $params{on_hangup} ) {
$self->_CAN_ON_HANGUP or croak "Cannot watch_io for 'on_hangup' in ".ref($self);
$watch->[3] = delete $params{on_hangup};
}
keys %params and croak "Unrecognised keys for ->watch_io - " . join( ", ", keys %params );
}
=head2 unwatch_io
$loop->unwatch_io( %params )
This method removes a watch on an IO handle which was previously installed by
C<watch_io>.
The C<%params> hash takes the following keys:
=over 8
=item handle => IO
The IO handle to remove the watch for.
=item on_read_ready => BOOL
If true, remove the watch for read-readiness.
=item on_write_ready => BOOL
If true, remove the watch for write-readiness.
( run in 0.476 second using v1.01-cache-2.11-cpan-140bd7fdf52 )