From bb8a6a435a4b7707e9fb0329c49671f495262016 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 16 Oct 2021 01:01:03 +0000 Subject: [PATCH] httpd/async: switch to level-triggered epoll 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 7bc1ad79..5a1655a1 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 7238650a..1651da88 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 a1ff65b6..53d0ad55 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; -- 2.44.0