about summary refs log tree commit homepage
path: root/lib/PublicInbox/InboxIdle.pm
diff options
context:
space:
mode:
authorEric Wong <e@yhbt.net>2020-07-02 03:32:56 +0000
committerEric Wong <e@yhbt.net>2020-07-02 19:51:14 +0000
commit1bc3707e3e0983c9aed898980ec8acf6501813f7 (patch)
treeee00a849c6746dfee4e58691926e4e3a2f954f4a /lib/PublicInbox/InboxIdle.pm
parent62575c514f07260cff5865b7bf122e41178b0476 (diff)
downloadpublic-inbox-1bc3707e3e0983c9aed898980ec8acf6501813f7.tar.gz
Anonymous subs cost over 5K each on x86-64.  So prefer the
less-recommended-but-still-documented way of using
Linux::Inotify2::watch to register watchers.

This also updates FakeInotify to detect modifications correctly
when used on systems with neither IO::KQueue nor
Linux::Inotify2.
Diffstat (limited to 'lib/PublicInbox/InboxIdle.pm')
-rw-r--r--lib/PublicInbox/InboxIdle.pm19
1 files changed, 15 insertions, 4 deletions
diff --git a/lib/PublicInbox/InboxIdle.pm b/lib/PublicInbox/InboxIdle.pm
index 59cb833f..bdb30284 100644
--- a/lib/PublicInbox/InboxIdle.pm
+++ b/lib/PublicInbox/InboxIdle.pm
@@ -36,12 +36,13 @@ sub in2_arm ($$) { # PublicInbox::Config::each_inbox callback
                 $ibx->{unlock_subs} and
                         die "BUG: $dir->{unlock_subs} should not exist";
                 $ibx->{unlock_subs} = $old_ibx->{unlock_subs};
-                $cur->[1]->cancel;
+                $cur->[1]->cancel; # Linux::Inotify2::Watch::cancel
         }
         $cur->[0] = $ibx;
 
         my $lock = "$dir/".($ibx->version >= 2 ? 'inbox.lock' : 'ssoma.lock');
-        $cur->[1] = $inot->watch($lock, $IN_MODIFY, sub { $ibx->on_unlock });
+        my $w = $cur->[1] = $inot->watch($lock, $IN_MODIFY);
+        $self->{on_unlock}->{$w->name} = $ibx;
 
         # TODO: detect deleted packs (and possibly other files)
 }
@@ -65,14 +66,24 @@ sub new {
         }
         $self->{inot} = $inot;
         $self->{pathmap} = {}; # inboxdir => [ ibx, watch1, watch2, watch3...]
+        $self->{on_unlock} = {}; # lock path => ibx
         refresh($self, $pi_config);
+        PublicInbox::FakeInotify::poll_once($self) if !$ino_cls;
         $self;
 }
 
 sub event_step {
         my ($self) = @_;
-        eval { $self->{inot}->poll }; # Linux::Inotify2::poll
-        warn "$self->{inot}->poll err: $@\n" if $@;
+        eval {
+                my @events = $self->{inot}->read; # Linux::Inotify2::read
+                my $on_unlock = $self->{on_unlock};
+                for my $ev (@events) {
+                        if (my $ibx = $on_unlock->{$ev->fullname}) {
+                                $ibx->on_unlock;
+                        }
+                }
+        };
+        warn "{inot}->read err: $@\n" if $@;
 }
 
 # for graceful shutdown in PublicInbox::Daemon,