1 # Copyright (C) 2020 all contributors <meta@public-inbox.org>
2 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
4 # for systems lacking Linux::Inotify2 or IO::KQueue, just emulates
5 # enough of Linux::Inotify2
6 package PublicInbox::FakeInotify;
8 use Time::HiRes qw(stat);
9 my $IN_CLOSE = 0x08 | 0x10; # match Linux inotify
11 my $poll_intvl = 2; # same as Filesys::Notify::Simple
12 my $for_cancel = bless \(my $x), 'PublicInbox::FakeInotify::Watch';
18 warn "E: FakeInotify->poll: $@\n" if $@;
19 PublicInbox::DS::add_timer($poll_intvl, poll_once($self));
24 my $self = bless { watch => {} }, __PACKAGE__;
25 PublicInbox::DS::add_timer($poll_intvl, poll_once($self));
29 # behaves like Linux::Inotify2->watch
31 my ($self, $path, $mask, $cb) = @_;
32 my @st = stat($path) or return;
33 $self->{watch}->{"$path\0$mask"} = [ @st, $cb ];
37 # behaves like non-blocking Linux::Inotify2->poll
40 my $watch = $self->{watch} or return;
41 for my $x (keys %$watch) {
42 my ($path, $mask) = split(/\0/, $x, 2);
43 my @now = stat($path) or next;
44 my $prv = $watch->{$x};
47 if ($prv->[10] != $now[10]) {
48 if (($mask & $IN_CLOSE) == $IN_CLOSE) {
56 package PublicInbox::FakeInotify::Watch;