# Copyrights 2011-2015 by [Mark Overmeer].
# For other contributors see ChangeLog.
# See the manual pages for details on the licensing terms.
# Pod stripped from pm file by OODoc 2.01.
use warnings;
use strict;
package IOMux::Poll;
use vars '$VERSION';
$VERSION = '0.13';
use base 'IOMux';
use Log::Report 'iomux';
use List::Util 'min';
use POSIX 'errno_h';
use IO::Poll;
use IO::Handle;
$SIG{PIPE} = 'IGNORE'; # pipes are handled in select
my $poll;
sub init($)
{ my ($self, $args) = @_;
$self->SUPER::init($args);
$poll ||= IO::Poll->new;
$self;
}
#-------------
sub poller {$poll}
#-------------
sub fdset($$$$$)
{ my ($self, $fileno, $state, $r, $w, $e) = @_;
my $conn = $self->handler($fileno) or return;
my $fh = $conn->fh;
my $mask = $poll->mask($fh);
if($state==0)
{ $mask &= ~POLLIN if $r;
$mask &= ~POLLOUT if $w;
$mask &= ~POLLERR if $e;
}
else
{ $mask |= POLLIN if $r;
$mask |= POLLOUT if $w;
$mask |= POLLERR if $e;
}
$poll->mask($fh, $mask);
}
sub one_go($$)
{ my ($self, $wait, $heartbeat) = @_;
my $numready = $poll->poll($wait);
$heartbeat->($self, $numready, undef)
if $heartbeat;
if($numready < 0)
{ return if $! == EINTR || $! == EAGAIN;
alert "Leaving loop with $!";
return 0;
}
$numready
or return 1;
$self->_ready(mux_read_flagged => POLLIN|POLLHUP);
$self->_ready(mux_write_flagged => POLLOUT);
$self->_ready(mux_except_flagged => POLLERR);
1; # success
}
# It would be nice to have an algorithm which is better than O(n)
sub _ready($$)
{ my ($self, $call, $mask) = @_;
my $handlers = $self->_handlers;
foreach my $fh ($poll->handles($mask))
{ my $fileno = $fh->fileno or next; # close filehandle
if(my $conn = $handlers->{$fileno})
{ # filehandle flagged
$conn->$call($fileno);
}
else
{ # Handler administration error, but when write and error it may
# be caused by read errors.
alert "connection for ".$fh->fileno." not registered in $call"
if $call eq 'mux_read_flagged';
}
}
}
1;
__END__