From 4f868db3675eeee5994edc4fe79a9a2583623747 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Mon, 24 Jun 2019 02:52:56 +0000 Subject: ds: reimplement IO::Poll support to look like epoll At least the subset of epoll we use. EPOLLET might be difficult to emulate if we end up using it. --- t/ds-poll.t | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 t/ds-poll.t (limited to 't') diff --git a/t/ds-poll.t b/t/ds-poll.t new file mode 100644 index 00000000..a397ee06 --- /dev/null +++ b/t/ds-poll.t @@ -0,0 +1,58 @@ +# Copyright (C) 2019 all contributors +# Licensed the same as Danga::Socket (and Perl5) +# License: GPL-1.0+ or Artistic-1.0-Perl +# +# +use strict; +use warnings; +use Test::More; +use PublicInbox::Syscall qw(:epoll); +my $cls = 'PublicInbox::DSPoll'; +use_ok $cls; +my $p = $cls->new; + +my ($r, $w, $x, $y); +pipe($r, $w) or die; +pipe($x, $y) or die; +is(epoll_ctl($p, EPOLL_CTL_ADD, fileno($r), EPOLLIN), 0, 'add EPOLLIN'); +my $events = []; +my $n = epoll_wait($p, 9, 0, $events); +is_deeply($events, [], 'no events set'); +is($n, 0, 'nothing ready, yet'); +is(epoll_ctl($p, EPOLL_CTL_ADD, fileno($w), EPOLLOUT|EPOLLONESHOT), 0, + 'add EPOLLOUT|EPOLLONESHOT'); +$n = epoll_wait($p, 9, -1, $events); +is($n, 1, 'got POLLOUT event'); +is($events->[0]->[0], fileno($w), '$w ready'); + +$n = epoll_wait($p, 9, 0, $events); +is($n, 0, 'nothing ready after oneshot'); +is_deeply($events, [], 'no events set after oneshot'); + +syswrite($w, '1') == 1 or die; +for my $t (0..1) { + $n = epoll_wait($p, 9, $t, $events); + is($events->[0]->[0], fileno($r), "level-trigger POLLIN ready #$t"); + is($n, 1, "only event ready #$t"); +} +syswrite($y, '1') == 1 or die; +is(epoll_ctl($p, EPOLL_CTL_ADD, fileno($x), EPOLLIN|EPOLLONESHOT), 0, + 'EPOLLIN|EPOLLONESHOT add'); +is(epoll_wait($p, 9, -1, $events), 2, 'epoll_wait has 2 ready'); +my @fds = sort(map { $_->[0] } @$events); +my @exp = sort((fileno($r), fileno($x))); +is_deeply(\@fds, \@exp, 'got both ready FDs'); + +# EPOLL_CTL_DEL doesn't matter for kqueue, we do it in native epoll +# to avoid a kernel-wide lock; but its not needed for native kqueue +# paths so DSKQXS makes it a noop (as did Danga::Socket::close). +SKIP: { + if ($cls ne 'PublicInbox::DSPoll') { + skip "$cls doesn't handle EPOLL_CTL_DEL", 2; + } + is(epoll_ctl($p, EPOLL_CTL_DEL, fileno($r), 0), 0, 'EPOLL_CTL_DEL OK'); + $n = epoll_wait($p, 9, 0, $events); + is($n, 0, 'nothing ready after EPOLL_CTL_DEL'); +}; + +done_testing; -- cgit v1.2.3-24-ge0c7