46 lines
1.0 KiB
PHP
46 lines
1.0 KiB
PHP
<?php
|
|
// phpcs:disable PEAR.Commenting.FileComment,PEAR.Commenting.ClassComment
|
|
|
|
/**
|
|
* File locking support.
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace IronKanban\Support;
|
|
|
|
/**
|
|
* Runs callbacks while holding an exclusive file lock.
|
|
*/
|
|
final class FileLock
|
|
{
|
|
/**
|
|
* Execute a callback under an exclusive lock.
|
|
*
|
|
* @param string $path Lock file path.
|
|
* @param callable $callback Callback to execute.
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public static function run(string $path, callable $callback): mixed
|
|
{
|
|
ensure_directory(dirname($path));
|
|
$handle = fopen($path, 'c+');
|
|
|
|
if ($handle === false) {
|
|
throw new \RuntimeException('Unable to open lock file: ' . $path);
|
|
}
|
|
|
|
try {
|
|
if (!flock($handle, LOCK_EX)) {
|
|
throw new \RuntimeException('Unable to lock file: ' . $path);
|
|
}
|
|
|
|
return $callback();
|
|
} finally {
|
|
flock($handle, LOCK_UN);
|
|
fclose($handle);
|
|
}
|
|
}
|
|
}
|