MediaWiki
REL1_19
|
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 }