Skip to content

Commit

Permalink
fix race conditions causing notices if directory does not exist
Browse files Browse the repository at this point in the history
  • Loading branch information
kkmuffme committed Jul 21, 2022
1 parent cac9ec9 commit 2dde842
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 7 deletions.
28 changes: 21 additions & 7 deletions src/Psalm/Config.php
Expand Up @@ -52,6 +52,7 @@
use function basename;
use function chdir;
use function class_exists;
use function clearstatcache;
use function count;
use function dirname;
use function error_log;
Expand Down Expand Up @@ -2268,6 +2269,7 @@ public function getPotentialComposerFilePathForClassLike(string $class): ?string

public static function removeCacheDirectory(string $dir): void
{
clearstatcache(true, $dir);
if (is_dir($dir)) {
$objects = scandir($dir, SCANDIR_SORT_NONE);

Expand All @@ -2276,17 +2278,29 @@ public static function removeCacheDirectory(string $dir): void
}

foreach ($objects as $object) {
if ($object !== '.' && $object !== '..') {
if (filetype($dir . '/' . $object) === 'dir') {
self::removeCacheDirectory($dir . '/' . $object);
} else {
unlink($dir . '/' . $object);
}
if ($object === '.' || $object === '..') {
continue;
}

// if it was deleted in the meantime/race condition with other psalm process
if (!file_exists($dir . '/' . $object)) {
continue;
}

if (filetype($dir . '/' . $object) === 'dir') {
self::removeCacheDirectory($dir . '/' . $object);
} else {
unlink($dir . '/' . $object);
}
}

reset($objects);
rmdir($dir);

// may have been removed in the meantime
clearstatcache(true, $dir);
if (is_dir($dir)) {
rmdir($dir);
}
}
}

Expand Down
7 changes: 7 additions & 0 deletions src/Psalm/Internal/Provider/ParserCacheProvider.php
Expand Up @@ -7,6 +7,7 @@
use Psalm\Config;
use RuntimeException;

use function clearstatcache;
use function error_log;
use function fclose;
use function file_get_contents;
Expand Down Expand Up @@ -302,6 +303,12 @@ public function saveFileContentHashes(): void
return;
}

// directory was removed, most likely due to a race condition with other psalm instances that were manually started at the same time
clearstatcache(true, $root_cache_directory);
if (!is_dir($root_cache_directory)) {
return;
}

$file_content_hashes = $this->new_file_content_hashes + $this->getExistingFileContentHashes();

$file_hashes_path = $root_cache_directory . DIRECTORY_SEPARATOR . self::FILE_HASHES;
Expand Down

0 comments on commit 2dde842

Please sign in to comment.