diff options
author | Eric Wong <e@80x24.org> | 2019-05-03 10:34:09 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2019-05-05 00:22:49 +0000 |
commit | 5aaea61844b92c452c201ce9832e3c5c68c6f84e (patch) | |
tree | 7afcdd8e62af3d0611bd24d04f7d44fe8faf7487 /lib/PublicInbox/DS.pm | |
parent | cd50d183273c105a7f08b1875ba6f7a51d9f8e9a (diff) | |
download | public-inbox-5aaea61844b92c452c201ce9832e3c5c68c6f84e.tar.gz |
Since our listen sockets are non-blocking and we may run multiple httpd|nntpd processes; we need a way to avoid thundering herds when there are multiple httpd|nntpd worker processes. EPOLLEXCLUSIVE was added just for that in Linux 4.5
Diffstat (limited to 'lib/PublicInbox/DS.pm')
-rw-r--r-- | lib/PublicInbox/DS.pm | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/lib/PublicInbox/DS.pm b/lib/PublicInbox/DS.pm index 543d3fdc..3ccc275d 100644 --- a/lib/PublicInbox/DS.pm +++ b/lib/PublicInbox/DS.pm @@ -78,6 +78,8 @@ our ( @Timers, # timers ); +# this may be set to zero with old kernels +our $EPOLLEXCLUSIVE = EPOLLEXCLUSIVE; Reset(); ##################################################################### @@ -666,11 +668,9 @@ This is normally (always?) called from your subclass via: =cut sub new { - my PublicInbox::DS $self = shift; + my ($self, $sock, $exclusive) = @_; $self = fields::new($self) unless ref $self; - my $sock = shift; - $self->{sock} = $sock; my $fd = fileno($sock); @@ -685,13 +685,23 @@ sub new { $self->{corked} = 0; $self->{read_push_back} = []; - $self->{event_watch} = POLLERR|POLLHUP|POLLNVAL; + my $ev = $self->{event_watch} = POLLERR|POLLHUP|POLLNVAL; _InitPoller(); if ($HaveEpoll) { - epoll_ctl($Epoll, EPOLL_CTL_ADD, $fd, $self->{event_watch}) - and die "couldn't add epoll watch for $fd\n"; + if ($exclusive) { + $ev = $self->{event_watch} = EPOLLIN|EPOLLERR|EPOLLHUP|$EPOLLEXCLUSIVE; + } +retry: + if (epoll_ctl($Epoll, EPOLL_CTL_ADD, $fd, $ev)) { + if ($!{EINVAL} && ($ev & $EPOLLEXCLUSIVE)) { + $EPOLLEXCLUSIVE = 0; # old kernel + $ev = $self->{event_watch} = EPOLLIN|EPOLLERR|EPOLLHUP; + goto retry; + } + die "couldn't add epoll watch for $fd: $!\n"; + } } elsif ($HaveKQueue) { # Add them to the queue but disabled for now |