From fa4bdf1cda3d48e2715841aa0bf5859e4b860ae5 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 21 Apr 2020 10:17:19 +0200 Subject: [PATCH] Make gen_stub parallelism safe If PHP-Parser is not yet installed, make sure we don't try to install it N times in parallel. --- build/gen_stub.php | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/build/gen_stub.php b/build/gen_stub.php index d784907048..5b2fee0317 100755 --- a/build/gen_stub.php +++ b/build/gen_stub.php @@ -997,16 +997,26 @@ function generateFunctionEntries(?string $className, array $funcInfos): string { return $code; } -function initPhpParser() { - $version = "4.3.0"; - $phpParserDir = __DIR__ . "/PHP-Parser-$version"; - if (!is_dir($phpParserDir)) { +function installPhpParser(string $version, string $phpParserDir) { + $lockFile = __DIR__ . "/PHP-Parser-install-lock"; + $lockFd = fopen($lockFile, 'w+'); + if (!flock($lockFd, LOCK_EX)) { + throw new Exception("Failed to acquire installation lock"); + } + + try { + // Check whether a parallel process has already installed PHP-Parser. + if (is_dir($phpParserDir)) { + return; + } + $cwd = getcwd(); chdir(__DIR__); - passthru("wget https://github.com/nikic/PHP-Parser/archive/v$version.tar.gz", $exit); + $tarName = "v$version.tar.gz"; + passthru("wget https://github.com/nikic/PHP-Parser/archive/$tarName", $exit); if ($exit !== 0) { - passthru("curl -LO https://github.com/nikic/PHP-Parser/archive/v$version.tar.gz", $exit); + passthru("curl -LO https://github.com/nikic/PHP-Parser/archive/$tarName", $exit); } if ($exit !== 0) { throw new Exception("Failed to download PHP-Parser tarball"); @@ -1014,12 +1024,23 @@ function initPhpParser() { if (!mkdir($phpParserDir)) { throw new Exception("Failed to create directory $phpParserDir"); } - passthru("tar xvzf v$version.tar.gz -C PHP-Parser-$version --strip-components 1", $exit); + passthru("tar xvzf $tarName -C PHP-Parser-$version --strip-components 1", $exit); if ($exit !== 0) { throw new Exception("Failed to extract PHP-Parser tarball"); } - unlink(__DIR__ . "/v$version.tar.gz"); + unlink(__DIR__ . "/$tarName"); chdir($cwd); + } finally { + flock($lockFd, LOCK_UN); + @unlink($lockFile); + } +} + +function initPhpParser() { + $version = "4.3.0"; + $phpParserDir = __DIR__ . "/PHP-Parser-$version"; + if (!is_dir($phpParserDir)) { + installPhpParser($version, $phpParserDir); } spl_autoload_register(function(string $class) use($phpParserDir) { -- 2.40.0