Skip to content

Instantly share code, notes, and snippets.

@ConConovaloff
Last active August 30, 2015 09:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ConConovaloff/6a4df0abe1f40a8461ca to your computer and use it in GitHub Desktop.
Save ConConovaloff/6a4df0abe1f40a8461ca to your computer and use it in GitHub Desktop.
php Lock on flock with blocked acquire
<?php
class Lock
{
/**
* @var string
*/
private $name;
/**
* @var string
*/
private $directory;
private $fp;
private $timeout_check;
private $time_expired;
/**
* @param string $name
* @param string $directory
* @param int|float $timeout_check
*/
public function __construct($name, $directory = '/tmp', $timeout_check = 0.5)
{
$this->name = $name;
$this->directory = rtrim($directory, '/');
$this->timeout_check = $timeout_check;
}
/**
* @param bool $blocked
* @param int|float|null $timeout seconds
* @return bool
*/
public function acquire($blocked = true, $timeout = null) {
$this->fp = fopen(sprintf("%s/%s.lock", $this->directory, $this->name), "w+");
$is_locked = flock($this->fp, LOCK_EX | LOCK_NB);
if (!$blocked) {
return $is_locked;
}
$this->setTimeout($timeout);
while (!$is_locked and !$this->isTimeExpired()) {
sleep($this->timeout_check);
$is_locked = $this->acquire(false);
}
return $is_locked;
}
public function release() {
flock($this->fp, LOCK_UN);
fclose($this->fp);
}
private function setTimeout($timeout) {
$this->time_expired = $timeout ? time() + $timeout : $timeout;
}
private function isTimeExpired() {
return $this->time_expired ? $this->time_expired < time() : False;
}
}
@ConConovaloff
Copy link
Author

Use:

$lock = new Lock('some_text');
$is_locked = $lock->acquire();
echo PHP_EOL . 'after acquire: ' . (int)$is_locked;

sleep(10); # do work

$lock->release();
echo PHP_EOL . 'after release';

With timeout:

$lock = new Lock('some_text');
$is_locked = $lock->acquire(true, 5);
echo PHP_EOL . 'after acquire: ' . (int)$is_locked;

if (! $is_locked) {
    thow new Exception('timeout expired')
}

sleep(10); # do work

$lock->release();
echo PHP_EOL . 'after release';

without blocking

$lock = new Lock('some_text');

while (! $lock->acquire(false)) {
    echo PHP_EOL 'wait... ';
}
echo PHP_EOL . 'after acquire: ' . (int)$is_locked;

sleep(10); # do work

$lock->release();
echo PHP_EOL . 'after release';

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment