Acme-Sort-Sleep
view release on metacpan or search on metacpan
local/lib/perl5/IO/Async/Handle.pm view on Meta::CPAN
The following named parameters may be passed to C<new> or C<configure>:
=head2 read_handle => IO
=head2 write_handle => IO
The reading and writing IO handles. Each must implement the C<fileno> method.
Primarily used for passing C<STDIN> / C<STDOUT>; see the SYNOPSIS section of
L<IO::Async::Stream> for an example.
=head2 handle => IO
The IO handle for both reading and writing; instead of passing each separately
as above. Must implement C<fileno> method in way that C<IO::Handle> does.
=head2 read_fileno => INT
=head2 write_fileno => INT
File descriptor numbers for reading and writing. If these are given as an
alternative to C<read_handle> or C<write_handle> then a new C<IO::Handle>
instance will be constructed around each.
=head2 on_read_ready => CODE
=head2 on_write_ready => CODE
=head2 on_closed => CODE
CODE references for event handlers.
=head2 want_readready => BOOL
=head2 want_writeready => BOOL
If present, enable or disable read- or write-ready notification as per the
C<want_readready> and C<want_writeready> methods.
It is required that a matching C<on_read_ready> or C<on_write_ready> are
available for any handle that is provided; either passed as a callback CODE
reference or as an overridden the method. I.e. if only a C<read_handle> is
given, then C<on_write_ready> can be absent. If C<handle> is used as a
shortcut, then both read and write-ready callbacks or methods are required.
If no IO handles are provided at construction time, the object is still
created but will not yet be fully-functional as a Handle. IO handles can be
assigned later using the C<set_handle> or C<set_handles> methods, or by
C<configure>. This may be useful when constructing an object to represent a
network connection, before the C<connect(2)> has actually been performed yet.
=cut
sub configure
{
my $self = shift;
my %params = @_;
if( exists $params{on_read_ready} ) {
$self->{on_read_ready} = delete $params{on_read_ready};
undef $self->{cb_r};
$self->_watch_read(0), $self->_watch_read(1) if $self->want_readready;
}
if( exists $params{on_write_ready} ) {
$self->{on_write_ready} = delete $params{on_write_ready};
undef $self->{cb_w};
$self->_watch_write(0), $self->_watch_write(1) if $self->want_writeready;
}
if( exists $params{on_closed} ) {
$self->{on_closed} = delete $params{on_closed};
}
if( defined $params{read_fileno} and defined $params{write_fileno} and
$params{read_fileno} == $params{write_fileno} ) {
$params{handle} = IO::Handle->new_from_fd( $params{read_fileno}, "r+" );
delete $params{read_fileno};
delete $params{write_fileno};
}
else {
$params{read_handle} = IO::Handle->new_from_fd( delete $params{read_fileno}, "r" )
if defined $params{read_fileno};
$params{write_handle} = IO::Handle->new_from_fd( delete $params{write_fileno}, "w" )
if defined $params{write_fileno};
}
# 'handle' is a shortcut for setting read_ and write_
if( exists $params{handle} ) {
$params{read_handle} = $params{handle};
$params{write_handle} = $params{handle};
delete $params{handle};
}
if( exists $params{read_handle} ) {
my $read_handle = delete $params{read_handle};
if( defined $read_handle ) {
if( !defined eval { $read_handle->fileno } ) {
croak 'Expected that read_handle can ->fileno';
}
unless( $self->can_event( 'on_read_ready' ) ) {
croak 'Expected either a on_read_ready callback or an ->on_read_ready method';
}
my @layers = PerlIO::get_layers( $read_handle );
if( grep m/^encoding\(/, @layers or grep m/^utf8$/, @layers ) {
# Only warn for now, because if it's UTF-8 by default but only
# passes ASCII then all will be well
carp "Constructing a ".ref($self)." with an encoding-enabled handle may not read correctly";
}
$self->{read_handle} = $read_handle;
$self->want_readready( defined $read_handle );
}
else {
$self->want_readready( 0 );
undef $self->{read_handle};
}
# In case someone has reopened the filehandles during an on_closed handler
undef $self->{handle_closing};
}
if( exists $params{write_handle} ) {
my $write_handle = delete $params{write_handle};
if( defined $write_handle ) {
if( !defined eval { $write_handle->fileno } ) {
croak 'Expected that write_handle can ->fileno';
}
unless( $self->can_event( 'on_write_ready' ) ) {
# This used not to be fatal. Make it just a warning for now.
carp 'A write handle was provided but neither a on_write_ready callback nor an ->on_write_ready method were. Perhaps you mean \'read_handle\' instead?';
}
$self->{write_handle} = $write_handle;
}
else {
$self->want_writeready( 0 );
undef $self->{write_handle};
}
# In case someone has reopened the filehandles during an on_closed handler
undef $self->{handle_closing};
}
if( exists $params{want_readready} ) {
$self->want_readready( delete $params{want_readready} );
}
if( exists $params{want_writeready} ) {
$self->want_writeready( delete $params{want_writeready} );
}
$self->SUPER::configure( %params );
}
# We'll be calling these any of three times
# adding to/removing from loop
# caller en/disables readiness checking
# changing filehandle
sub _watch_read
{
my $self = shift;
my ( $want ) = @_;
my $loop = $self->loop or return;
my $fh = $self->read_handle or return;
if( $want ) {
$self->{cb_r} ||= $self->make_event_cb( 'on_read_ready' );
$loop->watch_io(
handle => $fh,
on_read_ready => $self->{cb_r},
);
}
else {
$loop->unwatch_io(
handle => $fh,
on_read_ready => 1,
);
}
}
sub _watch_write
{
my $self = shift;
my ( $want ) = @_;
my $loop = $self->loop or return;
my $fh = $self->write_handle or return;
if( $want ) {
$self->{cb_w} ||= $self->make_event_cb( 'on_write_ready' );
$loop->watch_io(
handle => $fh,
on_write_ready => $self->{cb_w},
);
}
else {
$loop->unwatch_io(
local/lib/perl5/IO/Async/Handle.pm view on Meta::CPAN
=cut
sub new_close_future
{
my $self = shift;
push @{ $self->{close_futures} }, my $future = $self->loop->new_future;
$future->on_cancel(
$self->_capture_weakself( sub {
my $self = shift or return;
my $future = shift;
@{ $self->{close_futures} } = grep { $_ != $future } @{ $self->{close_futures} };
})
);
return $future;
}
=head2 read_handle
=head2 write_handle
$handle = $handle->read_handle
$handle = $handle->write_handle
These accessors return the underlying IO handles.
=cut
sub read_handle
{
my $self = shift;
return $self->{read_handle};
}
sub write_handle
{
my $self = shift;
return $self->{write_handle};
}
=head2 read_fileno
=head2 write_fileno
$fileno = $handle->read_fileno
$fileno = $handle->write_fileno
These accessors return the file descriptor numbers of the underlying IO
handles.
=cut
sub read_fileno
{
my $self = shift;
my $handle = $self->read_handle or return undef;
return $handle->fileno;
}
sub write_fileno
{
my $self = shift;
my $handle = $self->write_handle or return undef;
return $handle->fileno;
}
=head2 want_readready
=head2 want_writeready
$value = $handle->want_readready
$oldvalue = $handle->want_readready( $newvalue )
$value = $handle->want_writeready
$oldvalue = $handle->want_writeready( $newvalue )
These are the accessor for the C<want_readready> and C<want_writeready>
properties, which define whether the object is interested in knowing about
read- or write-readiness on the underlying file handle.
=cut
sub want_readready
{
my $self = shift;
if( @_ ) {
my ( $new ) = @_;
$new = !!$new;
return $new if !$new == !$self->{want_readready}; # compare bools
if( $new ) {
defined $self->read_handle or
croak 'Cannot want_readready in a Handle with no read_handle';
}
my $old = $self->{want_readready};
$self->{want_readready} = $new;
$self->_watch_read( $new );
return $old;
}
else {
return $self->{want_readready};
}
}
sub want_writeready
{
my $self = shift;
if( @_ ) {
my ( $new ) = @_;
$new = !!$new;
return $new if !$new == !$self->{want_writeready}; # compare bools
if( $new ) {
defined $self->write_handle or
croak 'Cannot want_writeready in a Handle with no write_handle';
}
( run in 1.579 second using v1.01-cache-2.11-cpan-d80b1682f3f )