From db1aadf450a15cbd4041c5f9bf5a0b16f66c2ad5 Mon Sep 17 00:00:00 2001 From: Craig Ringer Date: Wed, 12 Apr 2017 14:03:25 +0800 Subject: [PATCH] Add locking for initdb caching to allow parallel prove --- src/test/perl/PostgresNode.pm | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/test/perl/PostgresNode.pm b/src/test/perl/PostgresNode.pm index eef9f66..0eacd41 100644 --- a/src/test/perl/PostgresNode.pm +++ b/src/test/perl/PostgresNode.pm @@ -94,6 +94,7 @@ use Socket; use Test::More; use TestLib (); use Scalar::Util qw(blessed); +use Fcntl qw(:flock); our @EXPORT = qw( get_new_node @@ -477,15 +478,27 @@ sub _initdb_cached my $pgdata = $self->data_dir; my $cachedir = TestLib::tmp_check_dir() . "/initdb_cache"; + my $lockfile = TestLib::tmp_check_dir() . "/.initdb_cache.lock"; if (! -d $cachedir) { print(STDERR "initializing initdb cache\n"); - # initdb into a tempdir, then rename the result so we don't risk - # leaving failed initdb results around - my $temp_dbdir = TestLib::tempdir("initdb_cache_"); - $self->_initdb($temp_dbdir, %params); - rename($temp_dbdir, $cachedir); + open my $lockfh, ">", $lockfile + or die "cannot open $lockfile for writing: $1\n"; + flock($lockfh, LOCK_EX) + or die "cannot flock($lockfile) in exclusive mode: $!\n"; + # If running in parallel with other tests, someone else might've got + # the lock first and have swapped an initdb'd directory in already. + if (! -d $cachedir) + { + # initdb into a tempdir, then rename the result so we don't risk + # leaving failed initdb results around + my $temp_dbdir = TestLib::tempdir("initdb_cache_"); + $self->_initdb($temp_dbdir, %params); + rename($temp_dbdir, $cachedir); + } + flock($lockfh, LOCK_UN) + or die "cannot unlock $lockfile: $!"; } RecursiveCopy::copypath($cachedir, $pgdata); -- 2.5.5