mirror of
https://github.com/vichan-devel/vichan.git
synced 2025-01-19 01:24:05 +01:00
Refactor lock.php
This commit is contained in:
parent
00b05099f3
commit
760431606d
105
inc/lock.php
105
inc/lock.php
@ -1,43 +1,84 @@
|
||||
<?php
|
||||
class Lock {
|
||||
function __construct($key) {
|
||||
global $config;
|
||||
if ($config['lock']['enabled'] == 'fs') {
|
||||
$key = str_replace('/', '::', $key);
|
||||
$key = str_replace("\0", '', $key);
|
||||
|
||||
$this->f = fopen("tmp/locks/$key", "w");
|
||||
class Locks {
|
||||
private static function filesystem(string $key): Lock|false {
|
||||
$key = str_replace('/', '::', $key);
|
||||
$key = str_replace("\0", '', $key);
|
||||
|
||||
$fd = fopen("tmp/locks/$key", "w");
|
||||
if ($fd === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return new class($fd) implements Lock {
|
||||
// Resources have no type in php.
|
||||
private mixed $f;
|
||||
|
||||
|
||||
function __construct($fd) {
|
||||
$this->f = $fd;
|
||||
}
|
||||
|
||||
public function get(bool $nonblock = false): Lock|false {
|
||||
$wouldblock = false;
|
||||
flock($this->f, LOCK_SH | ($nonblock ? LOCK_NB : 0), $wouldblock);
|
||||
if ($nonblock && $wouldblock) {
|
||||
return false;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function get_ex(bool $nonblock = false): Lock|false {
|
||||
$wouldblock = false;
|
||||
flock($this->f, LOCK_EX | ($nonblock ? LOCK_NB : 0), $wouldblock);
|
||||
if ($nonblock && $wouldblock) {
|
||||
return false;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function free(): Lock {
|
||||
flock($this->f, LOCK_UN);
|
||||
return $this;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Get a shared lock
|
||||
function get($nonblock = false) {
|
||||
global $config;
|
||||
if ($config['lock']['enabled'] == 'fs') {
|
||||
$wouldblock = false;
|
||||
flock($this->f, LOCK_SH | ($nonblock ? LOCK_NB : 0), $wouldblock);
|
||||
if ($nonblock && $wouldblock) return false;
|
||||
}
|
||||
return $this;
|
||||
/**
|
||||
* No-op. Can be used for mocking.
|
||||
*/
|
||||
public static function none(): Lock|false {
|
||||
return new class() implements Lock {
|
||||
public function get(bool $nonblock = false): Lock|false {
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function get_ex(bool $nonblock = false): Lock|false {
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function free(): Lock {
|
||||
return $this;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Get an exclusive lock
|
||||
function get_ex($nonblock = false) {
|
||||
global $config;
|
||||
public static function get_lock(array $config, string $key): Lock|false {
|
||||
if ($config['lock']['enabled'] == 'fs') {
|
||||
$wouldblock = false;
|
||||
flock($this->f, LOCK_EX | ($nonblock ? LOCK_NB : 0), $wouldblock);
|
||||
if ($nonblock && $wouldblock) return false;
|
||||
return self::filesystem($key);
|
||||
} else {
|
||||
return self::none();
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
// Free a lock
|
||||
function free() {
|
||||
global $config;
|
||||
if ($config['lock']['enabled'] == 'fs') {
|
||||
flock($this->f, LOCK_UN);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
interface Lock {
|
||||
// Get a shared lock
|
||||
public function get(bool $nonblock = false): Lock|false;
|
||||
|
||||
// Get an exclusive lock
|
||||
public function get_ex(bool $nonblock = false): Lock|false;
|
||||
|
||||
// Free a lock
|
||||
public function free(): Lock;
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
class Queue {
|
||||
function __construct($key) { global $config;
|
||||
if ($config['queue']['enabled'] == 'fs') {
|
||||
$this->lock = new Lock($key);
|
||||
$this->lock = Locks::get_lock($config, $key);
|
||||
$key = str_replace('/', '::', $key);
|
||||
$key = str_replace("\0", '', $key);
|
||||
$this->key = "tmp/queue/$key/";
|
||||
|
Loading…
x
Reference in New Issue
Block a user