1 # Copyright (C) 2019-2020 all contributors <meta@public-inbox.org>
2 # Licensed the same as Danga::Socket (and Perl5)
3 # License: GPL-1.0+ or Artistic-1.0-Perl
4 # <https://www.gnu.org/licenses/gpl-1.0.txt>
5 # <https://dev.perl.org/licenses/artistic.html>
7 # poll(2) via IO::Poll core module. This makes poll look
8 # like epoll to simplify the code in DS.pm. This is NOT meant to be
9 # an all encompassing emulation of epoll via IO::Poll, but just to
10 # support cases public-inbox-nntpd/httpd care about.
11 package PublicInbox::DSPoll;
14 use parent qw(Exporter);
16 use PublicInbox::Syscall qw(EPOLLONESHOT EPOLLIN EPOLLOUT EPOLL_CTL_DEL);
17 our @EXPORT_OK = qw(epoll_ctl epoll_wait);
19 sub new { bless {}, $_[0] } # fd => events
22 my ($self, $op, $fd, $ev) = @_;
24 # not wasting time on error checking
25 if ($op != EPOLL_CTL_DEL) {
34 my ($self, $maxevents, $timeout_msec, $events) = @_;
36 while (my ($fd, $events) = each %$self) {
37 my $pevents = $events & EPOLLIN ? POLLIN : 0;
38 $pevents |= $events & EPOLLOUT ? POLLOUT : 0;
39 push(@pset, $fd, $pevents);
42 my $n = IO::Poll::_poll($timeout_msec, @pset);
44 for (my $i = 0; $i < @pset; ) {
46 my $revents = $pset[$i++] or next;
47 delete($self->{$fd}) if $self->{$fd} & EPOLLONESHOT;
48 push @$events, [ $fd ];
50 my $nevents = scalar @$events;
52 warn "BUG? poll() returned $n, but got $nevents";