Index: branches/FileBackend/phase3/includes/filerepo/backend/LockManager.php |
— | — | @@ -1,6 +1,6 @@ |
2 | 2 | <?php |
3 | 3 | /** |
4 | | - * FileBackend helper class for handling file locking. |
| 4 | + * Class for handling resource locking. |
5 | 5 | * Locks on resource keys can either be shared or exclusive. |
6 | 6 | * |
7 | 7 | * Implementations must keep track of what is locked by this proccess |
— | — | @@ -76,6 +76,69 @@ |
77 | 77 | } |
78 | 78 | |
79 | 79 | /** |
| 80 | + * LockManager helper class to handle scoped locks, which |
| 81 | + * release when an object is destroyed or goes out of scope. |
| 82 | + */ |
| 83 | +class ScopedLock { |
| 84 | + /** @var LockManager */ |
| 85 | + protected $manager; |
| 86 | + /** @var Status */ |
| 87 | + protected $status; |
| 88 | + /** @var Array List of resource paths*/ |
| 89 | + protected $paths; |
| 90 | + |
| 91 | + protected $type; // integer lock type |
| 92 | + |
| 93 | + /** |
| 94 | + * @param $manager LockManager |
| 95 | + * @param $paths Array List of storage paths |
| 96 | + * @param $type integer LockManager::LOCK_* constant |
| 97 | + * @param $status Status |
| 98 | + */ |
| 99 | + protected function __construct( |
| 100 | + LockManager $manager, array $paths, $type, Status $status |
| 101 | + ) { |
| 102 | + $this->manager = $manager; |
| 103 | + $this->paths = $paths; |
| 104 | + $this->status = $status; |
| 105 | + $this->type = $type; |
| 106 | + } |
| 107 | + |
| 108 | + protected function __clone() {} |
| 109 | + |
| 110 | + /** |
| 111 | + * Get a ScopedLock object representing a lock on resource paths. |
| 112 | + * Any locks are released once this object goes out of scope. |
| 113 | + * The status object is updated with any errors or warnings. |
| 114 | + * |
| 115 | + * @param $manager LockManager |
| 116 | + * @param $paths Array List of storage paths |
| 117 | + * @param $type integer LockManager::LOCK_* constant |
| 118 | + * @param $status Status |
| 119 | + * @return ScopedLock|null Returns null on failure |
| 120 | + */ |
| 121 | + public static function factory( |
| 122 | + LockManager $manager, array $paths, $type, Status $status |
| 123 | + ) { |
| 124 | + $lockStatus = $manager->lock( $paths, $type ); |
| 125 | + $status->merge( $lockStatus ); |
| 126 | + if ( $lockStatus->isOK() ) { |
| 127 | + return new self( $manager, $paths, $type, $status ); |
| 128 | + } |
| 129 | + return null; |
| 130 | + } |
| 131 | + |
| 132 | + function __destruct() { |
| 133 | + $wasOk = $this->status->isOK(); |
| 134 | + $this->status->merge( $this->manager->unlock( $this->paths, $this->type ) ); |
| 135 | + if ( $wasOk ) { |
| 136 | + // Make sure status is OK, despite any unlockFiles() fatals |
| 137 | + $this->status->setResult( true, $this->status->value ); |
| 138 | + } |
| 139 | + } |
| 140 | +} |
| 141 | + |
| 142 | +/** |
80 | 143 | * Simple version of LockManager based on using FS lock files. |
81 | 144 | * All locks are non-blocking, which avoids deadlocks. |
82 | 145 | * |
Index: branches/FileBackend/phase3/includes/filerepo/backend/FileBackend.php |
— | — | @@ -409,7 +409,7 @@ |
410 | 410 | * @return FileBackendScopedLock|null Returns null on failure |
411 | 411 | */ |
412 | 412 | final public function getScopedFileLocks( array $paths, $type, Status $status ) { |
413 | | - return FileBackendScopedLock::factory( $this, $paths, $type, $status ); |
| 413 | + return ScopedLock::factory( $this->lockManager, $paths, $type, $status ); |
414 | 414 | } |
415 | 415 | } |
416 | 416 | |
— | — | @@ -782,65 +782,3 @@ |
783 | 783 | return $relStoragePath; |
784 | 784 | } |
785 | 785 | } |
786 | | - |
787 | | -/** |
788 | | - * Class to handle scoped locks, which release when the object is destroyed |
789 | | - */ |
790 | | -class FileBackendScopedLock { |
791 | | - /** @var FileBackendBase */ |
792 | | - protected $backend; |
793 | | - /** @var Status */ |
794 | | - protected $status; |
795 | | - /** @var Array List of storage paths*/ |
796 | | - protected $paths; |
797 | | - protected $type; // integer lock type |
798 | | - |
799 | | - /** |
800 | | - * @param $backend FileBackendBase |
801 | | - * @param $paths Array List of storage paths |
802 | | - * @param $type integer LockManager::LOCK_EX, LockManager::LOCK_SH |
803 | | - * @param $status Status |
804 | | - */ |
805 | | - protected function __construct( |
806 | | - FileBackendBase $backend, array $paths, $type, Status $status |
807 | | - ) { |
808 | | - $this->backend = $backend; |
809 | | - $this->paths = $paths; |
810 | | - $this->status = $status; |
811 | | - $this->type = $type; |
812 | | - } |
813 | | - |
814 | | - protected function __clone() {} |
815 | | - |
816 | | - /** |
817 | | - * Get a status object resulting from an attempt to lock files. |
818 | | - * If the attempt is sucessful, the value of the status will be |
819 | | - * FileBackendScopedLock object which releases the locks when |
820 | | - * it goes out of scope. Otherwise, the value will be null. |
821 | | - * |
822 | | - * @param $backend FileBackendBase |
823 | | - * @param $files Array List of storage paths |
824 | | - * @param $type integer LockManager::LOCK_EX, LockManager::LOCK_SH |
825 | | - * @param $status Status |
826 | | - * @return FileBackendScopedLock|null |
827 | | - */ |
828 | | - public static function factory( |
829 | | - FileBackendBase $backend, array $files, $type, Status $status |
830 | | - ) { |
831 | | - $lockStatus = $backend->lockFiles( $files, $type ); |
832 | | - $status->merge( $lockStatus ); |
833 | | - if ( $lockStatus->isOK() ) { |
834 | | - return new self( $backend, $files, $type, $status ); |
835 | | - } |
836 | | - return null; |
837 | | - } |
838 | | - |
839 | | - function __destruct() { |
840 | | - $wasOk = $this->status->isOK(); |
841 | | - $this->status->merge( $this->backend->unlockFiles( $this->paths, $this->type ) ); |
842 | | - if ( $wasOk ) { |
843 | | - // Make sure status is OK, despite any unlockFiles() fatals |
844 | | - $this->status->setResult( true, $this->status->value ); |
845 | | - } |
846 | | - } |
847 | | -} |