php-ipc/src/Lock/FileLock.php

88 lines
1.6 KiB
PHP

<?php
namespace NoccyLabs\Ipc\Lock;
/**
* Simple filesystem-based lock
*
*
*/
class FileLock
{
const DEFAULT_TIMEOUT = 5;
protected $pathname;
protected $resource;
protected $locked = false;
/**
* Constructor
*
* @param string $pathname
*/
public function __construct(string $pathname)
{
if (!file_exists($pathname)) {
throw new \RuntimeException(sprintf(
"The file %s does not exist",
$pathname
));
}
$this->pathname = $pathname;
$this->resource = fopen($pathname, "r");
}
public function __destruct()
{
$this->release();
fclose($this->resource);
}
/**
* Acquire an exclusive lock
*
* @param float $timeout
* @return boolean
*/
public function acquire(float $timeout = self::DEFAULT_TIMEOUT):bool
{
if ($this->locked) {
return true;
}
$expire = microtime(true) + $timeout;
while (!flock($this->resource, LOCK_EX|LOCK_NB)) {
if (microtime(true)>$expire) {
return false;
}
usleep(1000);
}
$this->locked = true;
return true;
}
/**
* Release an acquired lock
*
* @return void
*/
public function release()
{
flock($this->resource, LOCK_UN);
$this->locked = false;
}
/**
* Check if the lock is acquired
*
* @return boolean
*/
public function isLocked():bool
{
return $this->locked;
}
}