From 2431ec2a5db67a9837eab95a9eeaeb4720425e81 Mon Sep 17 00:00:00 2001 From: "Eric Wong (Contractor, The Linux Foundation)" Date: Wed, 4 Apr 2018 21:25:00 +0000 Subject: [PATCH] v2writable: do not modify DBs while iterating for ->remove Xapian may become unhappy if a DB is modified during iteration: nntp://news.gmane.org/20180228004400.GU12724@survex.com --- lib/PublicInbox/V2Writable.pm | 46 ++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/lib/PublicInbox/V2Writable.pm b/lib/PublicInbox/V2Writable.pm index 5b4d9c0d..74953d34 100644 --- a/lib/PublicInbox/V2Writable.pm +++ b/lib/PublicInbox/V2Writable.pm @@ -256,6 +256,7 @@ sub remove_internal { my $mark; foreach my $mid (@$mids) { + my %gone; $srch->reopen->each_smsg_by_mid($mid, sub { my ($smsg) = @_; $smsg->load_expand; @@ -267,28 +268,35 @@ sub remove_internal { my $orig = $$msg; my $cur = PublicInbox::MIME->new($msg); if (content_id($cur) eq $cid) { - $mm->num_delete($smsg->num); - # $removed should only be set once assuming - # no bugs in our deduplication code: - $removed = $smsg; - $removed->{mime} = $cur; - my $oid = $smsg->{blob}; - if ($purge) { - $purge->{$oid} = 1; - } else { - ($mark, undef) = - $im->remove(\$orig, $cmt_msg); - } - $orig = undef; - $removed->num; # memoize this for callers - - foreach my $idx (@$parts) { - $idx->remote_remove($oid, $mid); - } - $self->{over}->remove_oid($oid, $mid); + $smsg->{mime} = $cur; + $gone{$smsg->num} = [ $smsg, \$orig ]; } 1; # continue }); + my $n = scalar keys %gone; + next unless $n; + if ($n > 1) { + warn "BUG: multiple articles linked to <$mid>\n", + join(',', sort keys %gone), "\n"; + } + foreach my $num (keys %gone) { + my ($smsg, $orig) = @{$gone{$num}}; + $mm->num_delete($num); + # $removed should only be set once assuming + # no bugs in our deduplication code: + $removed = $smsg; + my $oid = $smsg->{blob}; + if ($purge) { + $purge->{$oid} = 1; + } else { + ($mark, undef) = $im->remove($orig, $cmt_msg); + } + $orig = undef; + foreach my $idx (@$parts) { + $idx->remote_remove($oid, $mid); + } + $self->{over}->remove_oid($oid, $mid); + } $self->barrier; } -- 2.44.0