‪TYPO3CMS  ‪main
TYPO3\CMS\Core\Locking\ResourceMutex Class Reference

Public Member Functions

 __construct (private readonly LockFactory $lockFactory)
 
bool acquireLock (string $scope, string $key)
 
 releaseLock (string $scope)
 

Private Attributes

array $accessLocks = []
 
array $workerLocks = []
 

Detailed Description

Wrapper for locking API that uses two locks to not exhaust locking resources and still block properly.

The schematics here is:

  • ‪First acquire an access lock. This is using the type of the requested lock as key. Since the number of types is rather limited we can use the type as key as it will only eat up a limited number of lock resources on the system (files, semaphores)
  • ‪Second, we acquire the actual lock. We can be sure we are the only process at this very moment, hence we either get the lock for the given key or we get an error as we request a non-blocking mode.

Interleaving two locks is important, because the actual lock uses a hash value as key (see callers). If we would simply employ a normal blocking lock, we would get a potentially unlimited number of different locks. Depending on the available locking methods on the system we might run out of available resources: For instance maximum limit of semaphores is a system setting and applies to the whole system.

We therefore must make sure that page locks are destroyed again if they are not used anymore, such that we never use more locking resources than parallel requests.

In order to ensure this, we need to guarantee that no other process is waiting on a lock when the process currently having the lock on the lock is about to release the lock again.

This can only be achieved by using a non-blocking mode, such that a process is never put into wait state by the kernel, but only checks the availability of the lock. The access lock is our guard to be sure that no two processes are at the same time releasing/destroying a lock, whilst the other one tries to get a lock for this page lock.

The only drawback of this implementation is that we basically have to poll the availability of the page lock.

Note that the access lock resources are NEVER deleted/destroyed, otherwise the whole thing would be broken.

Definition at line 53 of file ResourceMutex.php.

Constructor & Destructor Documentation

◆ __construct()

TYPO3\CMS\Core\Locking\ResourceMutex::__construct ( private readonly LockFactory  $lockFactory)

Definition at line 65 of file ResourceMutex.php.

Member Function Documentation

◆ acquireLock()

bool TYPO3\CMS\Core\Locking\ResourceMutex::acquireLock ( string  $scope,
string  $key 
)

Acquire a specific lock for the given scope.

Exceptions
LockAcquireException
LockCreateException
Returns
‪bool True if we did not get the lock immediately and had to wait. This can be useful to know in the consumer since another process may have created something that we can re-use immediately.

Definition at line 76 of file ResourceMutex.php.

References TYPO3\CMS\Core\Locking\LockingStrategyInterface\LOCK_CAPABILITY_EXCLUSIVE, and TYPO3\CMS\Core\Locking\LockingStrategyInterface\LOCK_CAPABILITY_NOBLOCK.

◆ releaseLock()

TYPO3\CMS\Core\Locking\ResourceMutex::releaseLock ( string  $scope)

Release a worker specific lock.

Exceptions
LockAcquireException
LockAcquireWouldBlockException

Definition at line 118 of file ResourceMutex.php.

Member Data Documentation

◆ $accessLocks

array TYPO3\CMS\Core\Locking\ResourceMutex::$accessLocks = []
private

Definition at line 58 of file ResourceMutex.php.

◆ $workerLocks

array TYPO3\CMS\Core\Locking\ResourceMutex::$workerLocks = []
private

Definition at line 63 of file ResourceMutex.php.