From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.2 required=3.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 4440E1F568 for ; Mon, 11 Sep 2023 09:41:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=80x24.org; s=selector1; t=1694425298; bh=ODnh12DHxgcChQDm1R6faoSur9fk1qpdibBADMTv1aM=; h=From:To:Subject:Date:In-Reply-To:References:From; b=0B+Sy4bsBAeGQExkZXbHAkbCBxkttWJl3vzidvYY1iFEvoIuG7HDzxPJznpvP4EGU yb/CgLRF7c7H143FmUegk4bEFznvAOgOqHGMJUiM1X8KnOOVeReQsBdXOLD7tQud0K tLqcI57rgP37OllaqwM7qrLA+8EEyvvxxYEchJuo= From: Eric Wong To: meta@public-inbox.org Subject: [PATCH 5/7] dspoll: switch to the documented IO::Poll API Date: Mon, 11 Sep 2023 09:41:30 +0000 Message-ID: <20230911094132.75792-6-e@80x24.org> In-Reply-To: <20230911094132.75792-1-e@80x24.org> References: <20230911094132.75792-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: IO::Poll::_poll has always been an undocumented API. While it's remained working so far (since the early 2000s with Danga::Socket), I'm uncomfortable continuing with it moving forward since it's not documented (the leading underscore typically means it's not meant to be used by 3rd-parties). So switch to the documented API and just learn to live with some redundant object references and awkwardness in the API. --- lib/PublicInbox/DSPoll.pm | 43 +++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/lib/PublicInbox/DSPoll.pm b/lib/PublicInbox/DSPoll.pm index fc282de0..8ab5d19f 100644 --- a/lib/PublicInbox/DSPoll.pm +++ b/lib/PublicInbox/DSPoll.pm @@ -13,34 +13,33 @@ use v5.12; use IO::Poll; use PublicInbox::Syscall qw(EPOLLONESHOT EPOLLIN EPOLLOUT); -sub new { bless {}, __PACKAGE__ } # fd => events +sub new { bless { poll => IO::Poll->new }, __PACKAGE__ } # fd => events sub ep_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"; - } + $self->{poll}->poll($timeout_msec/1000) > 0 or return (@$events = ()); + my @io = $self->{poll}->handles(POLLIN|POLLOUT); + @$events = map { fileno($_) } @io; + for (@$events) { + my $io = shift @io; + $self->{poll}->remove($io) if delete($self->{oneshot}->{$_}); } } -sub ep_del { delete($_[0]->{fileno($_[1])}); 0 } -sub ep_add { $_[0]->{fileno($_[1])} = $_[2]; 0 } +sub ep_del { + my ($self, $io) = @_; + delete $self->{oneshot}->{fileno($io)}; + $self->{poll}->remove($io); + 0; +} + +sub ep_add { + my ($self, $io, $ev) = @_; + $self->{oneshot}->{fileno($io)} = 1 if $ev & EPOLLONESHOT; + $self->{poll}->mask($io, ($ev & EPOLLIN ? POLLIN : 0) | + ($ev & EPOLLOUT ? POLLOUT : 0)); + 0; +} no warnings 'once'; *ep_mod = \&ep_add;