Skip to content

Commit

Permalink
use lock to fix race condition
Browse files Browse the repository at this point in the history
  • Loading branch information
kkmuffme committed Jul 10, 2022
1 parent 6e27c23 commit c60ef5f
Showing 1 changed file with 30 additions and 1 deletion.
31 changes: 30 additions & 1 deletion src/Psalm/Internal/Provider/ParserCacheProvider.php
Expand Up @@ -8,9 +8,12 @@
use RuntimeException;

use function error_log;
use function fclose;
use function file_get_contents;
use function file_put_contents;
use function filemtime;
use function flock;
use function fopen;
use function gettype;
use function igbinary_serialize;
use function igbinary_unserialize;
Expand All @@ -28,9 +31,12 @@
use function trigger_error;
use function unlink;
use function unserialize;
use function usleep;

use const DIRECTORY_SEPARATOR;
use const E_USER_ERROR;
use const LOCK_EX;
use const LOCK_SH;
use const SCANDIR_SORT_NONE;

/**
Expand Down Expand Up @@ -184,7 +190,29 @@ private function getExistingFileContentHashes(): array
$file_hashes_path = $root_cache_directory . DIRECTORY_SEPARATOR . self::FILE_HASHES;

if ($root_cache_directory && is_readable($file_hashes_path)) {
$fp = fopen($file_hashes_path, 'r');
$max_wait_cycles = 5;
$has_lock = false;
while ($max_wait_cycles > 0) {
if (flock($fp, LOCK_SH)) {
$has_lock = true;
break;
}
$max_wait_cycles--;
usleep(50000);
}

if (!$has_lock) {
fclose($fp);
error_log('Could not acquire lock for content hashes file');
$this->existing_file_content_hashes = [];

return [];
}

// file_get_contents ignores any locks and gets the file, but we have the lock on $fp anyway
$hashes_encoded = (string) file_get_contents($file_hashes_path);
fclose($fp);

if (!$hashes_encoded) {
error_log('Unexpected value when loading from file content hashes');
Expand Down Expand Up @@ -281,7 +309,8 @@ public function saveFileContentHashes(): void

file_put_contents(
$file_hashes_path,
json_encode($file_content_hashes)
json_encode($file_content_hashes),
LOCK_EX
);
}

Expand Down

0 comments on commit c60ef5f

Please sign in to comment.