From 7fc6e30aeab9925bece4bb00f88bb91af5646aa2 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Thu, 29 Jul 2021 10:01:31 +0000 Subject: [PATCH] lei: close inotify FD in forked child Linux::Inotify2 2.3+ includes an ->fh method to give us the ability to safely close an FD without hitting EBADF (and automatically use FD_CLOEXEC). We'll still need a new wrapper class (LI2Wrap) to handle it for users of old versions, though. Link: http://lists.schmorp.de/pipermail/perl/2021q3/thread.html --- MANIFEST | 1 + lib/PublicInbox/DirIdle.pm | 11 +++++++++++ lib/PublicInbox/LEI.pm | 2 +- lib/PublicInbox/LI2Wrap.pm | 19 +++++++++++++++++++ 4 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 lib/PublicInbox/LI2Wrap.pm diff --git a/MANIFEST b/MANIFEST index a3913501..fb9f16bf 100644 --- a/MANIFEST +++ b/MANIFEST @@ -197,6 +197,7 @@ lib/PublicInbox/InputPipe.pm lib/PublicInbox/Isearch.pm lib/PublicInbox/KQNotify.pm lib/PublicInbox/LEI.pm +lib/PublicInbox/LI2Wrap.pm lib/PublicInbox/LeiALE.pm lib/PublicInbox/LeiAddWatch.pm lib/PublicInbox/LeiAuth.pm diff --git a/lib/PublicInbox/DirIdle.pm b/lib/PublicInbox/DirIdle.pm index 65896f95..d572c274 100644 --- a/lib/PublicInbox/DirIdle.pm +++ b/lib/PublicInbox/DirIdle.pm @@ -84,4 +84,15 @@ sub event_step { warn "$self->{inot}->read err: $@\n" if $@; } +sub force_close { + my ($self) = @_; + my $inot = delete $self->{inot} // return; + if ($inot->can('fh')) { # Linux::Inotify2 2.3+ + close($inot->fh) or warn "CLOSE ERROR: $!"; + } elsif ($inot->isa('Linux::Inotify2')) { + require PublicInbox::LI2Wrap; + PublicInbox::LI2Wrap::wrapclose($inot); + } +} + 1; diff --git a/lib/PublicInbox/LEI.pm b/lib/PublicInbox/LEI.pm index d9fd40fd..e6f763e1 100644 --- a/lib/PublicInbox/LEI.pm +++ b/lib/PublicInbox/LEI.pm @@ -556,7 +556,7 @@ sub _lei_atfork_child { } close $listener if $listener; undef $listener; - undef $dir_idle; + $dir_idle->force_close if $dir_idle; %PATH2CFG = (); $MDIR2CFGPATH = {}; eval 'no warnings; undef $PublicInbox::LeiNoteEvent::to_flush'; diff --git a/lib/PublicInbox/LI2Wrap.pm b/lib/PublicInbox/LI2Wrap.pm new file mode 100644 index 00000000..61cf4bee --- /dev/null +++ b/lib/PublicInbox/LI2Wrap.pm @@ -0,0 +1,19 @@ +# Copyright (C) all contributors +# License: AGPL-3.0+ + +# Wrapper for Linux::Inotify2 < 2.3 which lacked ->fh and auto-close +# Remove this when supported LTS/enterprise distros are all +# Linux::Inotify2 >= 2.3 +package PublicInbox::LI2Wrap; +use v5.10.1; +our @ISA = qw(Linux::Inotify2); + +sub wrapclose { + my ($inot) = @_; + my $fd = $inot->fileno; + open my $fh, '<&=', $fd or die "open <&= $fd $!"; +} + +sub DESTROY {} # no-op + +1 -- 2.44.0