File Coverage

lib/IOMux/Poll.pm
Criterion Covered Total %
statement 58 63 92.0
branch 17 30 56.6
condition 3 8 37.5
subroutine 13 14 92.8
pod 2 4 50.0
total 93 119 78.1


line stmt bran cond sub pod time code
1             # Copyrights 2011-2015 by [Mark Overmeer].
2             # For other contributors see ChangeLog.
3             # See the manual pages for details on the licensing terms.
4             # Pod stripped from pm file by OODoc 2.02.
5 8     8   4572 use warnings;
  8         16  
  8         276  
6 8     8   40 use strict;
  8         14  
  8         260  
7              
8             package IOMux::Poll;
9 8     8   38 use vars '$VERSION';
  8         13  
  8         469  
10             $VERSION = '1.00';
11              
12 8     8   40 use base 'IOMux';
  8         14  
  8         2330  
13              
14 8     8   48 use Log::Report 'iomux';
  8         15  
  8         51  
15              
16 8     8   1878 use List::Util 'min';
  8         22  
  8         391  
17 8     8   43 use POSIX 'errno_h';
  8         14  
  8         39  
18 8     8   3432 use IO::Poll;
  8         14  
  8         573  
19 8     8   58 use IO::Handle;
  8         12  
  8         4222  
20              
21             $SIG{PIPE} = 'IGNORE'; # pipes are handled in select
22              
23              
24             my $poll;
25             sub init($)
26 7     7 0 39 { my ($self, $args) = @_;
27 7         150 $self->SUPER::init($args);
28 7   33     89 $poll ||= IO::Poll->new;
29 7         96 $self;
30             }
31              
32             #-------------
33              
34 0     0 1 0 sub poller {$poll}
35              
36             #-------------
37              
38             sub fdset($$$$$)
39 32     32 1 71 { my ($self, $fileno, $state, $r, $w, $e) = @_;
40 32 100       83 my $conn = $self->handler($fileno) or return;
41 19         141 my $fh = $conn->fh;
42 19   100     187 my $mask = $poll->mask($fh) || 0;
43 19 100       346 if($state==0)
44 13 100       41 { $mask &= ~POLLIN if $r;
45 13 100       48 $mask &= ~POLLOUT if $w;
46 13 50       32 $mask &= ~POLLERR if $e;
47             }
48             else
49 6 50       34 { $mask |= POLLIN if $r;
50 6 50       22 $mask |= POLLOUT if $w;
51 6 50       20 $mask |= POLLERR if $e;
52             }
53 19         65 $poll->mask($fh, $mask);
54             }
55              
56             sub one_go($$)
57 12     12 0 25 { my ($self, $wait, $heartbeat) = @_;
58              
59 12         58 my $numready = $poll->poll($wait);
60              
61 12 50       1349003 $heartbeat->($self, $numready, undef)
62             if $heartbeat;
63              
64 12 50       60 if($numready < 0)
65 0 0 0     0 { return if $! == EINTR || $! == EAGAIN;
66 0         0 alert "leaving loop";
67 0         0 return 0;
68             }
69              
70             $numready
71 12 50       30 or return 1;
72            
73 12         54 $self->_ready(muxReadFlagged => POLLIN|POLLHUP);
74 12         851 $self->_ready(muxWriteFlagged => POLLOUT);
75 12         226 $self->_ready(muxExceptFlagged => POLLERR);
76              
77 12         213 1; # success
78             }
79              
80             # It would be nice to have an algorithm which is better than O(n)
81             sub _ready($$)
82 36     36   77 { my ($self, $call, $mask) = @_;
83 36         126 my $handlers = $self->_handlers;
84 36         120 foreach my $fh ($poll->handles($mask))
85 12 50       358 { my $fileno = $fh->fileno or next; # close filehandle
86 12 50       110 if(my $conn = $handlers->{$fileno})
87             { # filehandle flagged
88 12         73 $conn->$call($fileno);
89             }
90             else
91             { # Handler administration error, but when write and error it may
92             # be caused by read errors.
93 0 0         alert "connection for ".$fh->fileno." not registered in $call"
94             if $call eq 'muxReadFlagged';
95             }
96             }
97             }
98              
99             1;
100              
101             __END__