+sub _xdb_release {
+ my ($self) = @_;
+ my $xdb = delete $self->{xdb};
+ $xdb->commit_transaction;
+ $xdb->close;
+ _lock_release($self);
+}
+
+sub _xdb_acquire {
+ my ($self) = @_;
+ _lock_acquire($self);
+ my $dir = PublicInbox::Search->xdir($self->{git_dir});
+ my $flag = Search::Xapian::DB_OPEN;
+ my $xdb = Search::Xapian::WritableDatabase->new($dir, $flag);
+ $xdb->begin_transaction;
+ $self->{xdb} = $xdb;
+}
+
+sub _lock_acquire {
+ my ($self) = @_;
+ sysopen(my $lockfh, $self->{lock_path}, O_WRONLY|O_CREAT) or
+ die "failed to open lock $self->{lock_path}: $!\n";
+ flock($lockfh, LOCK_EX) or die "lock failed: $!\n";
+ $self->{lockfh} = $lockfh;
+}
+
+sub _lock_release {
+ my ($self) = @_;
+ my $lockfh = delete $self->{lockfh};
+ flock($lockfh, LOCK_UN) or die "unlock failed: $!\n";
+ close $lockfh or die "close failed: $!\n";
+}
+