diff options
author | Eric Wong <e@80x24.org> | 2019-06-26 06:36:27 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2019-06-26 06:36:27 +0000 |
commit | 84d8920b92686e975929aebe845b6d4ea0a9ef0d (patch) | |
tree | 91a1123aaa44ad8fbb63c9dbf912d6dca95b0818 /lib/PublicInbox/DSPoll.pm | |
parent | c19a4e88f49ba3496751c4b87ebcfa0f6b47f0ce (diff) | |
parent | c30b4427b340aeb242273a7b890fbd7e50132f51 (diff) | |
download | public-inbox-84d8920b92686e975929aebe845b6d4ea0a9ef0d.tar.gz |
* origin/nntp-tls: (59 commits) ds: ->write must not clobber empty wbuf array Makefile: skip DSKQXS in global syntax check ds: reduce overhead of tempfile creation Revert "ci: require IO::KQueue on FreeBSD, for now" ds: reimplement IO::Poll support to look like epoll ds: split out IO::KQueue-specific code daemon: use FreeBSD accept filters on non-NNTP daemon: set TCP_DEFER_ACCEPT on everything but NNTP nntp: send greeting immediately for plain sockets ci: require IO::KQueue on FreeBSD, for now nntp: lazily allocate and stash rbuf ds: flush_write runs ->write callbacks even if closed nntp: simplify long response logic and fix nesting ds: always use EV_ADD with EV_SET nntp: reduce allocations for greeting ds: allow ->write callbacks to syswrite directly daemon: use SSL_MODE_RELEASE_BUFFERS t/nntpd-tls: slow client connection test nntp: call SSL_shutdown in normal cases ds|nntp: use CORE::close on socket ...
Diffstat (limited to 'lib/PublicInbox/DSPoll.pm')
-rw-r--r-- | lib/PublicInbox/DSPoll.pm | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/lib/PublicInbox/DSPoll.pm b/lib/PublicInbox/DSPoll.pm new file mode 100644 index 00000000..e65640a8 --- /dev/null +++ b/lib/PublicInbox/DSPoll.pm @@ -0,0 +1,58 @@ +# Copyright (C) 2019 all contributors <meta@public-inbox.org> +# Licensed the same as Danga::Socket (and Perl5) +# License: GPL-1.0+ or Artistic-1.0-Perl +# <https://www.gnu.org/licenses/gpl-1.0.txt> +# <https://dev.perl.org/licenses/artistic.html> +# +# poll(2) via IO::Poll core module. This makes poll look +# like epoll to simplify the code in DS.pm. This is NOT meant to be +# an all encompassing emulation of epoll via IO::Poll, but just to +# support cases public-inbox-nntpd/httpd care about. +package PublicInbox::DSPoll; +use strict; +use warnings; +use parent qw(Exporter); +use IO::Poll; +use PublicInbox::Syscall qw(EPOLLONESHOT EPOLLIN EPOLLOUT EPOLL_CTL_DEL); +our @EXPORT = qw(epoll_ctl epoll_wait); + +sub new { bless {}, $_[0] } # fd => events + +sub epoll_ctl { + my ($self, $op, $fd, $ev) = @_; + + # not wasting time on error checking + if ($op != EPOLL_CTL_DEL) { + $self->{$fd} = $ev; + } else { + delete $self->{$fd}; + } + 0; +} + +sub epoll_wait { + my ($self, $maxevents, $timeout_msec, $events) = @_; + my @pset; + while (my ($fd, $events) = each %$self) { + my $pevents = $events & EPOLLIN ? POLLIN : 0; + $pevents |= $events & EPOLLOUT ? POLLOUT : 0; + push(@pset, $fd, $pevents); + } + @$events = (); + my $n = IO::Poll::_poll($timeout_msec, @pset); + if ($n >= 0) { + for (my $i = 0; $i < @pset; ) { + my $fd = $pset[$i++]; + my $revents = $pset[$i++] or next; + delete($self->{$fd}) if $self->{$fd} & EPOLLONESHOT; + push @$events, [ $fd ]; + } + my $nevents = scalar @$events; + if ($n != $nevents) { + warn "BUG? poll() returned $n, but got $nevents"; + } + } + $n; +} + +1; |