Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
ScopedLock
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 4
56
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 factory
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 release
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 __destruct
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2/**
3 * @license GPL-2.0-or-later
4 * @file
5 */
6namespace Wikimedia\LockManager;
7
8use 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 */
19class 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 */
92class_alias( ScopedLock::class, 'ScopedLock' );