‪TYPO3CMS  ‪main
ResourceMutex.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
17 
21 
54 {
58  private array ‪$accessLocks = [];
59 
63  private array ‪$workerLocks = [];
64 
65  public function ‪__construct(private readonly ‪LockFactory $lockFactory) {}
66 
76  public function ‪acquireLock(string $scope, string $key): bool
77  {
78  $this->accessLocks[$scope] = $this->lockFactory->createLocker($scope);
79  $this->workerLocks[$scope] = $this->lockFactory->createLocker(
80  $key,
82  );
83  $hadToWaitForLock = false;
84  do {
85  if (!$this->accessLocks[$scope]->acquire()) {
86  throw new \RuntimeException('Could not acquire access lock for "' . $scope . '".', 1601923209);
87  }
88  try {
89  $locked = $this->workerLocks[$scope]->acquire(
91  );
93  // Somebody else has the lock, we keep waiting.
94  // First release the access lock, it will be acquired in next iteration again.
95  $this->accessLocks[$scope]->release();
96  // Mark "We had to wait".
97  $hadToWaitForLock = true;
98  // Now lets make a short break (20ms) until we try again, since
99  // the page generation by the lock owner will take a while.
100  usleep(20000);
101  continue;
102  }
103  $this->accessLocks[$scope]->release();
104  if ($locked) {
105  break;
106  }
107  throw new \RuntimeException('Could not acquire process lock for "' . $scope . '" with key "' . $key . '".', 1601923215);
108  } while (true);
109  return $hadToWaitForLock;
110  }
111 
118  public function ‪releaseLock(string $scope): void
119  {
120  if ($this->accessLocks[$scope] ?? null) {
121  if (!$this->accessLocks[$scope]->acquire()) {
122  throw new \RuntimeException('Could not acquire access lock for "' . $scope . '".', 1601923319);
123  }
124  $this->workerLocks[$scope]->release();
125  $this->workerLocks[$scope]->destroy();
126  $this->workerLocks[$scope] = null;
127  $this->accessLocks[$scope]->release();
128  $this->accessLocks[$scope] = null;
129  }
130  }
131 }
‪TYPO3\CMS\Core\Locking\ResourceMutex
Definition: ResourceMutex.php:54
‪TYPO3\CMS\Core\Locking\LockingStrategyInterface\LOCK_CAPABILITY_NOBLOCK
‪const LOCK_CAPABILITY_NOBLOCK
Definition: LockingStrategyInterface.php:40
‪TYPO3\CMS\Core\Locking
‪TYPO3\CMS\Core\Locking\LockingStrategyInterface\LOCK_CAPABILITY_EXCLUSIVE
‪const LOCK_CAPABILITY_EXCLUSIVE
Definition: LockingStrategyInterface.php:30
‪TYPO3\CMS\Core\Locking\Exception\LockAcquireWouldBlockException
Definition: LockAcquireWouldBlockException.php:21
‪TYPO3\CMS\Core\Locking\ResourceMutex\$workerLocks
‪array $workerLocks
Definition: ResourceMutex.php:63
‪TYPO3\CMS\Core\Locking\Exception\LockAcquireException
Definition: LockAcquireException.php:23
‪TYPO3\CMS\Core\Locking\Exception\LockCreateException
Definition: LockCreateException.php:23
‪TYPO3\CMS\Core\Locking\ResourceMutex\acquireLock
‪bool acquireLock(string $scope, string $key)
Definition: ResourceMutex.php:76
‪TYPO3\CMS\Core\Locking\ResourceMutex\releaseLock
‪releaseLock(string $scope)
Definition: ResourceMutex.php:118
‪TYPO3\CMS\Core\Locking\ResourceMutex\$accessLocks
‪array $accessLocks
Definition: ResourceMutex.php:58
‪TYPO3\CMS\Core\Locking\LockFactory
Definition: LockFactory.php:27
‪TYPO3\CMS\Core\Locking\ResourceMutex\__construct
‪__construct(private readonly LockFactory $lockFactory)
Definition: ResourceMutex.php:65