MediaWiki  REL1_19
LockManager.php
Go to the documentation of this file.
00001 <?php
00028 abstract class LockManager {
00030         protected $lockTypeMap = array(
00031                 self::LOCK_SH => self::LOCK_SH,
00032                 self::LOCK_UW => self::LOCK_EX, // subclasses may use self::LOCK_SH
00033                 self::LOCK_EX => self::LOCK_EX
00034         );
00035 
00037         protected $locksHeld = array();
00038 
00039         /* Lock types; stronger locks have higher values */
00040         const LOCK_SH = 1; // shared lock (for reads)
00041         const LOCK_UW = 2; // shared lock (for reads used to write elsewhere)
00042         const LOCK_EX = 3; // exclusive lock (for writes)
00043 
00049         public function __construct( array $config ) {}
00050 
00058         final public function lock( array $paths, $type = self::LOCK_EX ) {
00059                 return $this->doLock( array_unique( $paths ), $this->lockTypeMap[$type] );
00060         }
00061 
00069         final public function unlock( array $paths, $type = self::LOCK_EX ) {
00070                 return $this->doUnlock( array_unique( $paths ), $this->lockTypeMap[$type] );
00071         }
00072 
00079         final protected static function sha1Base36( $path ) {
00080                 return wfBaseConvert( sha1( $path ), 16, 36, 31 );
00081         }
00082 
00090         abstract protected function doLock( array $paths, $type );
00091 
00099         abstract protected function doUnlock( array $paths, $type );
00100 }
00101 
00111 class ScopedLock {
00113         protected $manager;
00115         protected $status;
00117         protected $paths;
00118 
00119         protected $type; // integer lock type
00120 
00127         protected function __construct(
00128                 LockManager $manager, array $paths, $type, Status $status
00129         ) {
00130                 $this->manager = $manager;
00131                 $this->paths = $paths;
00132                 $this->status = $status;
00133                 $this->type = $type;
00134         }
00135 
00136         protected function __clone() {}
00137 
00149         public static function factory(
00150                 LockManager $manager, array $paths, $type, Status $status
00151         ) {
00152                 $lockStatus = $manager->lock( $paths, $type );
00153                 $status->merge( $lockStatus );
00154                 if ( $lockStatus->isOK() ) {
00155                         return new self( $manager, $paths, $type, $status );
00156                 }
00157                 return null;
00158         }
00159 
00160         function __destruct() {
00161                 $wasOk = $this->status->isOK();
00162                 $this->status->merge( $this->manager->unlock( $this->paths, $this->type ) );
00163                 if ( $wasOk ) {
00164                         // Make sure status is OK, despite any unlockFiles() fatals
00165                         $this->status->setResult( true, $this->status->value );
00166                 }
00167         }
00168 }
00169 
00174 class NullLockManager extends LockManager {
00175         protected function doLock( array $paths, $type ) {
00176                 return Status::newGood();
00177         }
00178 
00179         protected function doUnlock( array $paths, $type ) {
00180                 return Status::newGood();
00181         }
00182 }