Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
0.00% |
0 / 15 |
|
0.00% |
0 / 4 |
CRAP | |
0.00% |
0 / 1 |
| ScopedLock | |
0.00% |
0 / 14 |
|
0.00% |
0 / 4 |
56 | |
0.00% |
0 / 1 |
| __construct | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
| factory | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
12 | |||
| release | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| __destruct | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
| 1 | <?php |
| 2 | /** |
| 3 | * @license GPL-2.0-or-later |
| 4 | * @file |
| 5 | */ |
| 6 | namespace Wikimedia\LockManager; |
| 7 | |
| 8 | use StatusValue; |
| 9 | |
| 10 | /** |
| 11 | * Self-releasing locks. |
| 12 | * |
| 13 | * Helper for consumers of LockManager, to create locks that automatically |
| 14 | * release when an object is destroyed or goes out of scope. |
| 15 | * |
| 16 | * @ingroup LockManager |
| 17 | * @since 1.19 |
| 18 | */ |
| 19 | class ScopedLock { |
| 20 | /** @var LockManager */ |
| 21 | protected $manager; |
| 22 | /** @var StatusValue */ |
| 23 | protected $status; |
| 24 | /** @var array Map of lock types to resource paths */ |
| 25 | protected $pathsByType; |
| 26 | |
| 27 | /** |
| 28 | * @param LockManager $manager |
| 29 | * @param array $pathsByType Map of lock types to path lists |
| 30 | * @param StatusValue $status |
| 31 | */ |
| 32 | protected function __construct( |
| 33 | LockManager $manager, array $pathsByType, StatusValue $status |
| 34 | ) { |
| 35 | $this->manager = $manager; |
| 36 | $this->pathsByType = $pathsByType; |
| 37 | $this->status = $status; |
| 38 | } |
| 39 | |
| 40 | /** |
| 41 | * Get a ScopedLock object representing a lock on resource paths. |
| 42 | * Any locks are released once this object goes out of scope. |
| 43 | * The StatusValue object is updated with any errors or warnings. |
| 44 | * |
| 45 | * @param LockManager $manager |
| 46 | * @param array $paths List of storage paths or map of lock types to path lists |
| 47 | * @param int|string $type LockManager::LOCK_* constant or "mixed" and $paths |
| 48 | * can be a map of types to paths (since 1.22). Otherwise $type should be an |
| 49 | * integer and $paths should be a list of paths. |
| 50 | * @param StatusValue $status |
| 51 | * @param int $timeout Timeout in seconds (0 means non-blocking) (since 1.22) |
| 52 | * @return ScopedLock|null Returns null on failure |
| 53 | */ |
| 54 | public static function factory( |
| 55 | LockManager $manager, array $paths, $type, StatusValue $status, $timeout = 0 |
| 56 | ) { |
| 57 | $pathsByType = is_int( $type ) ? [ $type => $paths ] : $paths; |
| 58 | $lockStatus = $manager->lockByType( $pathsByType, $timeout ); |
| 59 | $status->merge( $lockStatus ); |
| 60 | if ( $lockStatus->isOK() ) { |
| 61 | return new self( $manager, $pathsByType, $status ); |
| 62 | } |
| 63 | |
| 64 | return null; |
| 65 | } |
| 66 | |
| 67 | /** |
| 68 | * Release a scoped lock and set any errors in the attached StatusValue object. |
| 69 | * This is useful for early release of locks before function scope is destroyed. |
| 70 | * This is the same as setting the lock object to null. |
| 71 | * |
| 72 | * @param ScopedLock|null &$lock |
| 73 | * @since 1.21 |
| 74 | */ |
| 75 | public static function release( ?ScopedLock &$lock = null ) { |
| 76 | $lock = null; |
| 77 | } |
| 78 | |
| 79 | /** |
| 80 | * Release the locks when this goes out of scope |
| 81 | */ |
| 82 | public function __destruct() { |
| 83 | $wasOk = $this->status->isOK(); |
| 84 | $this->status->merge( $this->manager->unlockByType( $this->pathsByType ) ); |
| 85 | if ( $wasOk ) { |
| 86 | // Make sure StatusValue is OK, despite any unlockFiles() fatals |
| 87 | $this->status->setResult( true, $this->status->value ); |
| 88 | } |
| 89 | } |
| 90 | } |
| 91 | /** @deprecated class alias since 1.46 */ |
| 92 | class_alias( ScopedLock::class, 'ScopedLock' ); |