From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.0 required=3.0 tests=ALL_TRUSTED,AWL,BAYES_00 shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 89E611FD5B for ; Sat, 16 Oct 2021 01:01:04 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Subject: [PATCH 12/12] httpd/async: switch to level-triggered epoll Date: Sat, 16 Oct 2021 01:01:03 +0000 Message-Id: <20211016010103.30825-13-e@80x24.org> In-Reply-To: <20211016010103.30825-1-e@80x24.org> References: <20211016010103.30825-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: We'll save ourselves some code here and let the kernel do more work, instead. --- Documentation/technical/ds.txt | 3 +-- lib/PublicInbox/HTTPD/Async.pm | 16 +++++----------- lib/PublicInbox/Qspawn.pm | 1 - 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/Documentation/technical/ds.txt b/Documentation/technical/ds.txt index 7bc1ad79ce0c..5a1655a1450e 100644 --- a/Documentation/technical/ds.txt +++ b/Documentation/technical/ds.txt @@ -77,8 +77,7 @@ New features which (if any) events it's interested in for the next loop iteration. * Edge-triggering available via EPOLLET or EV_CLEAR. These reduce wakeups - for unidirectional classes (e.g. PublicInbox::Listener sockets, - and pipes via PublicInbox::HTTPD::Async). + for unidirectional classes when throughput is more important than fairness. * IO::Socket::SSL support (for NNTPS, STARTTLS+NNTP, HTTPS) diff --git a/lib/PublicInbox/HTTPD/Async.pm b/lib/PublicInbox/HTTPD/Async.pm index 7238650aff97..1651da88ac03 100644 --- a/lib/PublicInbox/HTTPD/Async.pm +++ b/lib/PublicInbox/HTTPD/Async.pm @@ -17,7 +17,7 @@ package PublicInbox::HTTPD::Async; use strict; use parent qw(PublicInbox::DS); use Errno qw(EAGAIN); -use PublicInbox::Syscall qw(EPOLLIN EPOLLET); +use PublicInbox::Syscall qw(EPOLLIN); # This is called via: $env->{'pi-httpd.async'}->() # $io is a read-only pipe ($rpipe) for now, but may be a @@ -39,7 +39,7 @@ sub new { }, $class; my $pp = tied *$io; $pp->{fh}->blocking(0) // die "$io->blocking(0): $!"; - $self->SUPER::new($io, EPOLLIN | EPOLLET); + $self->SUPER::new($io, EPOLLIN); } sub event_step { @@ -54,15 +54,12 @@ sub event_step { my $r = sysread($sock, my $buf, 65536); if ($r) { $self->{fh}->write($buf); # may call $http->close - if ($http->{sock}) { # !closed - $self->requeue; - # let other clients get some work done, too - return; - } + # let other clients get some work done, too + return if $http->{sock}; # !closed # else: fall through to close below... } elsif (!defined $r && $! == EAGAIN) { - return; # EPOLLET means we'll be notified + return; # EPOLLIN means we'll be notified } # Done! Error handling will happen in $self->{fh}->close @@ -89,9 +86,6 @@ sub async_pass { $self->{http} = $http; $self->{fh} = $fh; - - # either hit EAGAIN or ->requeue to keep EPOLLET happy - event_step($self); } # may be called as $forward->close in PublicInbox::HTTP or EOF (event_step) diff --git a/lib/PublicInbox/Qspawn.pm b/lib/PublicInbox/Qspawn.pm index a1ff65b65324..53d0ad55ee84 100644 --- a/lib/PublicInbox/Qspawn.pm +++ b/lib/PublicInbox/Qspawn.pm @@ -192,7 +192,6 @@ sub event_step { sub rd_hdr ($) { my ($self) = @_; # typically used for reading CGI headers - # we must loop until EAGAIN for EPOLLET in HTTPD/Async.pm # We also need to check EINTR for generic PSGI servers. my $ret; my $total_rd = 0;