1
0
mirror of https://github.com/vichan-devel/vichan.git synced 2024-12-18 10:25:55 +01:00
vichan/inc/lock.php

85 lines
1.7 KiB
PHP
Raw Normal View History

<?php
2024-02-16 14:47:20 +01:00
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;
2024-02-16 14:18:55 +01:00
}
2024-02-16 14:47:20 +01:00
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;
}
};
2024-02-16 14:18:55 +01:00
}
2024-02-16 14:47:20 +01:00
/**
* 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;
}
};
2024-02-16 14:18:55 +01:00
}
2024-02-16 14:47:20 +01:00
public static function get_lock(array $config, string $key): Lock|false {
2024-02-16 14:18:55 +01:00
if ($config['lock']['enabled'] == 'fs') {
2024-02-16 14:47:20 +01:00
return self::filesystem($key);
} else {
return self::none();
2024-02-16 14:18:55 +01:00
}
}
2024-02-16 14:47:20 +01:00
}
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;
2024-02-16 14:18:55 +01:00
// Free a lock
2024-02-16 14:47:20 +01:00
public function free(): Lock;
}