From: Eric Wong Date: Fri, 8 Nov 2024 12:06:46 +0000 (+0000) Subject: EOFpipe: avoid uninitialized variables in lei tests X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1f056b85cbcb039fcbb73b6acebd1014944e6899;p=thirdparty%2Fpublic-inbox.git EOFpipe: avoid uninitialized variables in lei tests EINTR can happen due to spurious wakeups and lead to uninitialized variable warnings when comparing the result of ->do_read to a numeric value. Thus avoid EINTR by making the pipe non-blocking on initialization. Furthermore, our ->do_read API is overkill and not appropriate for only detecting EOF on a pipe since it is designed for parsing network protocols. Relying on level-triggering makes more sense here, since we only want to detect EOF and don't have to worry about event loop monopolization. --- diff --git a/lib/PublicInbox/EOFpipe.pm b/lib/PublicInbox/EOFpipe.pm index 77b699a2d..3eaa0e4e7 100644 --- a/lib/PublicInbox/EOFpipe.pm +++ b/lib/PublicInbox/EOFpipe.pm @@ -4,21 +4,29 @@ package PublicInbox::EOFpipe; use v5.12; use parent qw(PublicInbox::DS); -use PublicInbox::Syscall qw(EPOLLIN EPOLLONESHOT $F_SETPIPE_SZ); +use PublicInbox::Syscall qw(EPOLLIN $F_SETPIPE_SZ); +use Errno qw(EAGAIN); sub new { my (undef, $rd, @cb_args) = @_; my $self = bless { cb_args => \@cb_args }, __PACKAGE__; # 4096: page size fcntl($rd, $F_SETPIPE_SZ, 4096) if $F_SETPIPE_SZ; - $self->SUPER::new($rd, EPOLLIN|EPOLLONESHOT); + $rd->blocking(0); # avoid EINTR + $self->SUPER::new($rd, EPOLLIN); # level trigger for spurious wakeup } sub event_step { my ($self) = @_; - if ($self->do_read(my $buf, 1) == 0) { # auto-closed + my $r = sysread $self->{sock}, my $buf, 1; + if (!defined $r) { + warn "W: EOFpipe read: $!\n" if $! != EAGAIN; + } elsif ($r == 0) { + $self->close; my ($cb, @args) = @{delete $self->{cb_args}}; $cb->(@args); + } else { + warn "BUG? EOFpipe read $r bytes, expected 0\n"; } }