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-2020 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             # This code is part of distribution IOMux. Meta-POD processed with OODoc
6             # into POD and HTML manual-pages. See README.md
7             # Copyright Mark Overmeer. Licensed under the same terms as Perl itself.
8              
9             package IOMux::Poll;
10 8     8   4925 use vars '$VERSION';
  8         14  
  8         405  
11             $VERSION = '1.01';
12              
13 8     8   41 use base 'IOMux';
  8         8  
  8         2517  
14              
15 8     8   44 use warnings;
  8         15  
  8         222  
16 8     8   34 use strict;
  8         14  
  8         252  
17              
18 8     8   37 use Log::Report 'iomux';
  8         49  
  8         30  
19              
20 8     8   1751 use List::Util 'min';
  8         14  
  8         371  
21 8     8   35 use POSIX 'errno_h';
  8         15  
  8         33  
22 8     8   2207 use IO::Poll;
  8         15  
  8         541  
23 8     8   41 use IO::Handle;
  8         15  
  8         3894  
24              
25             $SIG{PIPE} = 'IGNORE'; # pipes are handled in select
26              
27              
28             my $poll;
29             sub init($)
30 7     7 0 18 { my ($self, $args) = @_;
31 7         32 $self->SUPER::init($args);
32 7   33     56 $poll ||= IO::Poll->new;
33 7         103 $self;
34             }
35              
36             #-------------
37              
38 0     0 1 0 sub poller {$poll}
39              
40             #-------------
41              
42             sub fdset($$$$$)
43 32     32 1 96 { my ($self, $fileno, $state, $r, $w, $e) = @_;
44 32 100       157 my $conn = $self->handler($fileno) or return;
45 19         119 my $fh = $conn->fh;
46 19   100     166 my $mask = $poll->mask($fh) || 0;
47 19 100       370 if($state==0)
48 13 100       33 { $mask &= ~POLLIN if $r;
49 13 100       45 $mask &= ~POLLOUT if $w;
50 13 50       50 $mask &= ~POLLERR if $e;
51             }
52             else
53 6 50       24 { $mask |= POLLIN if $r;
54 6 50       24 $mask |= POLLOUT if $w;
55 6 50       24 $mask |= POLLERR if $e;
56             }
57 19         54 $poll->mask($fh, $mask);
58             }
59              
60             sub one_go($$)
61 12     12 0 33 { my ($self, $wait, $heartbeat) = @_;
62              
63 12         53 my $numready = $poll->poll($wait);
64              
65 12 50       468094 $heartbeat->($self, $numready, undef)
66             if $heartbeat;
67              
68 12 50       42 if($numready < 0)
69 0 0 0     0 { return if $! == EINTR || $! == EAGAIN;
70 0         0 alert "leaving loop";
71 0         0 return 0;
72             }
73              
74             $numready
75 12 50       28 or return 1;
76            
77 12         42 $self->_ready(muxReadFlagged => POLLIN|POLLHUP);
78 12         487 $self->_ready(muxWriteFlagged => POLLOUT);
79 12         234 $self->_ready(muxExceptFlagged => POLLERR);
80              
81 12         208 1; # success
82             }
83              
84             # It would be nice to have an algorithm which is better than O(n)
85             sub _ready($$)
86 36     36   124 { my ($self, $call, $mask) = @_;
87 36         92 my $handlers = $self->_handlers;
88 36         92 foreach my $fh ($poll->handles($mask))
89 12 50       336 { my $fileno = $fh->fileno or next; # close filehandle
90 12 50       341 if(my $conn = $handlers->{$fileno})
91             { # filehandle flagged
92 12         55 $conn->$call($fileno);
93             }
94             else
95             { # Handler administration error, but when write and error it may
96             # be caused by read errors.
97 0 0         alert "connection for ".$fh->fileno." not registered in $call"
98             if $call eq 'muxReadFlagged';
99             }
100             }
101             }
102              
103             1;
104              
105             __END__