public-inbox.git  about / heads / tags
an "archives first" approach to mailing lists
blob a7055ec9e8c6a548bb2064309b46606088390ca2 1641 bytes (raw)
$ git show HEAD:lib/PublicInbox/DSPoll.pm	# shows this blob on the CLI

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
 
# Copyright (C) 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 v5.12;
use IO::Poll;
use PublicInbox::Syscall qw(EPOLLONESHOT EPOLLIN EPOLLOUT);
use Carp qw(carp);
use Errno ();

sub new { bless {}, __PACKAGE__ } # fd => events

sub ep_wait {
	my ($self, $timeout_msec, $events) = @_;
	my (@pset, $n, $fd, $revents, $nval);
	while (my ($fd, $events) = each %$self) {
		my $pevents = $events & EPOLLIN ? POLLIN : 0;
		$pevents |= $events & EPOLLOUT ? POLLOUT : 0;
		push(@pset, $fd, $pevents);
	}
	@$events = ();
	$n = IO::Poll::_poll($timeout_msec, @pset) or return; # timeout expired
	return if $n < 0 && $! == Errno::EINTR; # caller recalculates timeout
	die "poll: $!" if $n < 0;
	while (defined($fd = shift @pset)) {
		$revents = shift @pset or next; # no event
		if ($revents & POLLNVAL) {
			carp "E: FD=$fd invalid in poll";
			delete $self->{$fd};
			$nval = 1;
		} else {
			delete $self->{$fd} if $self->{$fd} & EPOLLONESHOT;
			push @$events, $fd;
		}
	}
	if ($nval && !@$events) {
		$! = Errno::EBADF;
		die "poll: $!";
	}
}

sub ep_del { delete($_[0]->{fileno($_[1])}); 0 }
sub ep_add { $_[0]->{fileno($_[1])} = $_[2]; 0 }

no warnings 'once';
*ep_mod = \&ep_add;

1;

git clone https://public-inbox.org/public-inbox.git
git clone http://7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd.onion/public-inbox.git