class FlockStore
FlockStore is a PersistingStoreInterface implementation using the FileSystem flock.
Original implementation in \Symfony\Component\Filesystem\LockHandler.
@author Jérémy Derussé <jeremy@derusse.com> @author Grégoire Pineau <lyrixx@lyrixx.info> @author Romain Neutron <imprec@gmail.com> @author Nicolas Grekas <p@tchwork.com>
Hierarchy
- class \Symfony\Component\Lock\Store\FlockStore implements \Symfony\Component\Lock\BlockingStoreInterface, \Symfony\Component\Lock\SharedLockStoreInterface
Expanded class hierarchy of FlockStore
1 file declares its use of FlockStore
- LockableTrait.php in vendor/
symfony/ console/ Command/ LockableTrait.php
File
-
vendor/
symfony/ lock/ Store/ FlockStore.php, line 31
Namespace
Symfony\Component\Lock\StoreView source
class FlockStore implements BlockingStoreInterface, SharedLockStoreInterface {
private ?string $lockPath;
/**
* @param string|null $lockPath the directory to store the lock, defaults to the system's temporary directory
*
* @throws LockStorageException If the lock directory doesn’t exist or is not writable
*/
public function __construct(?string $lockPath = null) {
if (!is_dir($lockPath ??= sys_get_temp_dir())) {
if (false === @mkdir($lockPath, 0777, true) && !is_dir($lockPath)) {
throw new InvalidArgumentException(\sprintf('The FlockStore directory "%s" does not exists and cannot be created.', $lockPath));
}
}
elseif (!is_writable($lockPath)) {
throw new InvalidArgumentException(\sprintf('The FlockStore directory "%s" is not writable.', $lockPath));
}
$this->lockPath = $lockPath;
}
public function save(Key $key) : void {
$this->lock($key, false, false);
}
public function saveRead(Key $key) : void {
$this->lock($key, true, false);
}
public function waitAndSave(Key $key) : void {
$this->lock($key, false, true);
}
public function waitAndSaveRead(Key $key) : void {
$this->lock($key, true, true);
}
private function lock(Key $key, bool $read, bool $blocking) : void {
$handle = null;
// The lock is maybe already acquired.
if ($key->hasState(__CLASS__)) {
[
$stateRead,
$handle,
] = $key->getState(__CLASS__);
// Check for promotion or demotion
if ($stateRead === $read) {
return;
}
}
if (!$handle) {
$fileName = \sprintf('%s/sf.%s.%s.lock', $this->lockPath, substr(preg_replace('/[^a-z0-9\\._-]+/i', '-', $key), 0, 50), strtr(substr(base64_encode(hash('sha256', $key, true)), 0, 7), '/', '_'));
// Silence error reporting
set_error_handler(function ($type, $msg) use (&$error) {
$error = $msg;
});
try {
if (!($handle = fopen($fileName, 'r+') ?: fopen($fileName, 'r'))) {
if ($handle = fopen($fileName, 'x')) {
chmod($fileName, 0666);
}
elseif (!($handle = fopen($fileName, 'r+') ?: fopen($fileName, 'r'))) {
usleep(100);
// Give some time for chmod() to complete
$handle = fopen($fileName, 'r+') ?: fopen($fileName, 'r');
}
}
} finally {
restore_error_handler();
}
}
if (!$handle) {
throw new LockStorageException($error, 0, null);
}
// On Windows, even if PHP doc says the contrary, LOCK_NB works, see
// https://bugs.php.net/54129
if (!flock($handle, ($read ? \LOCK_SH : \LOCK_EX) | ($blocking ? 0 : \LOCK_NB))) {
fclose($handle);
throw new LockConflictedException();
}
$key->setState(__CLASS__, [
$read,
$handle,
]);
$key->markUnserializable();
}
public function putOffExpiration(Key $key, float $ttl) : void {
// do nothing, the flock locks forever.
}
public function delete(Key $key) : void {
// The lock is maybe not acquired.
if (!$key->hasState(__CLASS__)) {
return;
}
$handle = $key->getState(__CLASS__)[1];
flock($handle, \LOCK_UN | \LOCK_NB);
fclose($handle);
$key->removeState(__CLASS__);
}
public function exists(Key $key) : bool {
return $key->hasState(__CLASS__);
}
}
Members
Title Sort descending | Modifiers | Object type | Summary | Overriden Title |
---|---|---|---|---|
FlockStore::$lockPath | private | property | ||
FlockStore::delete | public | function | Removes a resource from the storage. | Overrides PersistingStoreInterface::delete |
FlockStore::exists | public | function | Returns whether or not the resource exists in the storage. | Overrides PersistingStoreInterface::exists |
FlockStore::lock | private | function | ||
FlockStore::putOffExpiration | public | function | Extends the TTL of a resource. | Overrides PersistingStoreInterface::putOffExpiration |
FlockStore::save | public | function | Stores the resource if it's not locked by someone else. | Overrides PersistingStoreInterface::save |
FlockStore::saveRead | public | function | Stores the resource if it's not locked for reading by someone else. | Overrides SharedLockStoreInterface::saveRead |
FlockStore::waitAndSave | public | function | Waits until a key becomes free, then stores the resource. | Overrides BlockingStoreInterface::waitAndSave |
FlockStore::waitAndSaveRead | public | function | ||
FlockStore::__construct | public | function |