sub remove_eml_i { # each_inbox callback
my ($ibx, $arg) = @_;
my ($self, $eml, $loc) = @$arg;
+
eval {
- my $im = _importer_for($self, $ibx);
- $im->remove($eml, 'spam');
- if (my $scrub = $ibx->filter($im)) {
- my $scrubbed = $scrub->scrub($eml, 1);
- if ($scrubbed && $scrubbed != REJECT) {
- $im->remove($scrubbed, 'spam');
+ # try to avoid taking a lock or unnecessary spawning
+ my $im = $self->{importers}->{"$ibx"};
+ my $scrubbed;
+ if ((!$im || !$im->active) && $ibx->over) {
+ if (content_exists($ibx, $eml)) {
+ # continue
+ } elsif (my $scrub = $ibx->filter($im)) {
+ $scrubbed = $scrub->scrub($eml, 1);
+ if ($scrubbed && $scrubbed != REJECT &&
+ !content_exists($ibx, $scrubbed)) {
+ return;
+ }
+ } else {
+ return;
}
}
+
+ $im //= _importer_for($self, $ibx); # may spawn fast-import
+ $im->remove($eml, 'spam');
+ $scrubbed //= do {
+ my $scrub = $ibx->filter($im);
+ $scrub ? $scrub->scrub($eml, 1) : undef;
+ };
+ if ($scrubbed && $scrubbed != REJECT) {
+ $im->remove($scrubbed, 'spam');
+ }
};
if ($@) {
warn "error removing spam at: $loc from $ibx->{name}: $@\n";
sub watch_atfork_parent ($) {
my ($self) = @_;
_done_for_now($self);
+ PublicInbox::Sigfd::block_signals();
}
sub imap_idle_requeue ($) { # DS::add_timer callback
return if $self->{quit};
my $idle_todo = $self->{idle_todo};
if ($idle_todo && @$idle_todo) {
- watch_atfork_parent($self);
- while (my $url_intvl = shift(@$idle_todo)) {
- imap_idle_fork($self, $url_intvl);
- }
+ my $oldset = watch_atfork_parent($self);
+ eval {
+ while (my $url_intvl = shift(@$idle_todo)) {
+ imap_idle_fork($self, $url_intvl);
+ }
+ };
+ PublicInbox::Sigfd::sig_setmask($oldset);
+ die $@ if $@;
}
goto(&fs_scan_step) if $self->{mdre};
}
sub poll_fetch_fork ($) { # DS::add_timer callback
my ($self, $intvl, $urls) = @{$_[0]};
return if $self->{quit};
- watch_atfork_parent($self);
- defined(my $pid = fork) or die "fork: $!";
- if ($pid == 0) {
+ my $oldset = watch_atfork_parent($self);
+ my $pid = fork;
+ if (defined($pid) && $pid == 0) {
watch_atfork_child($self);
if ($urls->[0] =~ m!\Aimaps?://!i) {
watch_imap_fetch_all($self, $urls);
}
_exit(0);
}
+ PublicInbox::Sigfd::sig_setmask($oldset);
+ die "fork: $!" unless defined $pid;
$self->{poll_pids}->{$pid} = [ $intvl, $urls ];
PublicInbox::DS::dwaitpid($pid, \&poll_fetch_reap, $self);
}