TYPO3 v15 dev-main snapshot ()
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Core\Locking;
|
||||
|
||||
use TYPO3\CMS\Core\Locking\Exception\LockCreateException;
|
||||
use TYPO3\CMS\Core\SingletonInterface;
|
||||
|
||||
/**
|
||||
* Factory class to retrieve a locking method
|
||||
*/
|
||||
class LockFactory implements SingletonInterface
|
||||
{
|
||||
/**
|
||||
* @var array<class-string, bool>
|
||||
*/
|
||||
protected array $lockingStrategy = [
|
||||
SemaphoreLockStrategy::class => true,
|
||||
FileLockStrategy::class => true,
|
||||
SimpleLockStrategy::class => true,
|
||||
];
|
||||
|
||||
/**
|
||||
* Add a locking method.
|
||||
*
|
||||
* @param class-string $className
|
||||
*/
|
||||
public function addLockingStrategy(string $className): void
|
||||
{
|
||||
$interfaces = class_implements($className);
|
||||
if (isset($interfaces[LockingStrategyInterface::class])) {
|
||||
$this->lockingStrategy[$className] = true;
|
||||
} else {
|
||||
throw new \InvalidArgumentException('The given class name ' . $className . ' does not implement the required LockingStrategyInterface interface.', 1425990198);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a locking method.
|
||||
*
|
||||
* @param class-string $className
|
||||
*/
|
||||
public function removeLockingStrategy(string $className): void
|
||||
{
|
||||
unset($this->lockingStrategy[$className]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get best matching locking method
|
||||
*
|
||||
* @param string $id ID to identify this lock in the system
|
||||
* @param int-mask-of<LockingStrategyInterface::LOCK_CAPABILITY_*> $capabilities LockingStrategyInterface::LOCK_CAPABILITY_* elements combined with bit-wise OR
|
||||
* @return LockingStrategyInterface Class name for a locking method
|
||||
* @throws LockCreateException if no locker could be created with the requested capabilities
|
||||
*/
|
||||
public function createLocker(string $id, int $capabilities = LockingStrategyInterface::LOCK_CAPABILITY_EXCLUSIVE): LockingStrategyInterface
|
||||
{
|
||||
$queue = new \SplPriorityQueue();
|
||||
|
||||
/** @var class-string<LockingStrategyInterface> $method */
|
||||
foreach ($this->lockingStrategy as $method => $_) {
|
||||
$supportedCapabilities = $capabilities & $method::getCapabilities();
|
||||
if ($supportedCapabilities === $capabilities) {
|
||||
$queue->insert($method, $method::getPriority());
|
||||
}
|
||||
}
|
||||
if ($queue->count() > 0) {
|
||||
$className = $queue->top();
|
||||
// We use 'new' here on purpose!
|
||||
// Locking might be used very early in the bootstrap process, where makeInstance() does not work
|
||||
return new $className($id);
|
||||
}
|
||||
throw new LockCreateException('Could not find a matching locking method with requested capabilities.', 1425990190);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user