Merge "Minor installer/upgrader cleanups"
[lhc/web/wiklou.git] / includes / filebackend / lockmanager / MemcLockManager.php
index 24d96e0..81ce424 100644 (file)
  */
 class MemcLockManager extends QuorumLockManager {
        /** @var array Mapping of lock types to the type actually used */
-       protected $lockTypeMap = array(
+       protected $lockTypeMap = [
                self::LOCK_SH => self::LOCK_SH,
                self::LOCK_UW => self::LOCK_SH,
                self::LOCK_EX => self::LOCK_EX
-       );
+       ];
 
        /** @var array Map server names to MemcachedBagOStuff objects */
-       protected $bagOStuffs = array();
+       protected $bagOStuffs = [];
 
        /** @var array (server name => bool) */
-       protected $serversUp = array();
+       protected $serversUp = [];
 
        /** @var string Random UUID */
        protected $session = '';
@@ -72,10 +72,10 @@ class MemcLockManager extends QuorumLockManager {
 
                $memcConfig = isset( $config['memcConfig'] )
                        ? $config['memcConfig']
-                       : array( 'class' => 'MemcachedPhpBagOStuff' );
+                       : [ 'class' => 'MemcachedPhpBagOStuff' ];
 
                foreach ( $config['lockServers'] as $name => $address ) {
-                       $params = array( 'servers' => array( $address ) ) + $memcConfig;
+                       $params = [ 'servers' => [ $address ] ] + $memcConfig;
                        $cache = ObjectCache::newFromParams( $params );
                        if ( $cache instanceof MemcachedBagOStuff ) {
                                $this->bagOStuffs[$name] = $cache;
@@ -90,9 +90,9 @@ class MemcLockManager extends QuorumLockManager {
 
        // @todo Change this code to work in one batch
        protected function getLocksOnServer( $lockSrv, array $pathsByType ) {
-               $status = Status::newGood();
+               $status = StatusValue::newGood();
 
-               $lockedPaths = array();
+               $lockedPaths = [];
                foreach ( $pathsByType as $type => $paths ) {
                        $status->merge( $this->doGetLocksOnServer( $lockSrv, $paths, $type ) );
                        if ( $status->isOK() ) {
@@ -112,7 +112,7 @@ class MemcLockManager extends QuorumLockManager {
 
        // @todo Change this code to work in one batch
        protected function freeLocksOnServer( $lockSrv, array $pathsByType ) {
-               $status = Status::newGood();
+               $status = StatusValue::newGood();
 
                foreach ( $pathsByType as $type => $paths ) {
                        $status->merge( $this->doFreeLocksOnServer( $lockSrv, $paths, $type ) );
@@ -126,13 +126,13 @@ class MemcLockManager extends QuorumLockManager {
         * @param string $lockSrv
         * @param array $paths
         * @param string $type
-        * @return Status
+        * @return StatusValue
         */
        protected function doGetLocksOnServer( $lockSrv, array $paths, $type ) {
-               $status = Status::newGood();
+               $status = StatusValue::newGood();
 
                $memc = $this->getCache( $lockSrv );
-               $keys = array_map( array( $this, 'recordKeyForPath' ), $paths ); // lock records
+               $keys = array_map( [ $this, 'recordKeyForPath' ], $paths ); // lock records
 
                // Lock all of the active lock record keys...
                if ( !$this->acquireMutexes( $memc, $keys ) ) {
@@ -202,13 +202,13 @@ class MemcLockManager extends QuorumLockManager {
         * @param string $lockSrv
         * @param array $paths
         * @param string $type
-        * @return Status
+        * @return StatusValue
         */
        protected function doFreeLocksOnServer( $lockSrv, array $paths, $type ) {
-               $status = Status::newGood();
+               $status = StatusValue::newGood();
 
                $memc = $this->getCache( $lockSrv );
-               $keys = array_map( array( $this, 'recordKeyForPath' ), $paths ); // lock records
+               $keys = array_map( [ $this, 'recordKeyForPath' ], $paths ); // lock records
 
                // Lock all of the active lock record keys...
                if ( !$this->acquireMutexes( $memc, $keys ) ) {
@@ -254,10 +254,10 @@ class MemcLockManager extends QuorumLockManager {
 
        /**
         * @see QuorumLockManager::releaseAllLocks()
-        * @return Status
+        * @return StatusValue
         */
        protected function releaseAllLocks() {
-               return Status::newGood(); // not supported
+               return StatusValue::newGood(); // not supported
        }
 
        /**
@@ -276,6 +276,7 @@ class MemcLockManager extends QuorumLockManager {
         * @return MemcachedBagOStuff|null
         */
        protected function getCache( $lockSrv ) {
+               /** @var BagOStuff $memc */
                $memc = null;
                if ( isset( $this->bagOStuffs[$lockSrv] ) ) {
                        $memc = $this->bagOStuffs[$lockSrv];
@@ -298,14 +299,14 @@ class MemcLockManager extends QuorumLockManager {
         * @return string
         */
        protected function recordKeyForPath( $path ) {
-               return implode( ':', array( __CLASS__, 'locks', $this->sha1Base36Absolute( $path ) ) );
+               return implode( ':', [ __CLASS__, 'locks', $this->sha1Base36Absolute( $path ) ] );
        }
 
        /**
         * @return array An empty lock structure for a key
         */
        protected static function newLockArray() {
-               return array( self::LOCK_SH => array(), self::LOCK_EX => array() );
+               return [ self::LOCK_SH => [], self::LOCK_EX => [] ];
        }
 
        /**
@@ -328,7 +329,7 @@ class MemcLockManager extends QuorumLockManager {
         * @return bool
         */
        protected function acquireMutexes( MemcachedBagOStuff $memc, array $keys ) {
-               $lockedKeys = array();
+               $lockedKeys = [];
 
                // Acquire the keys in lexicographical order, to avoid deadlock problems.
                // If P1 is waiting to acquire a key P2 has, P2 can't also be waiting for a key P1 has.
@@ -337,20 +338,21 @@ class MemcLockManager extends QuorumLockManager {
                // Try to quickly loop to acquire the keys, but back off after a few rounds.
                // This reduces memcached spam, especially in the rare case where a server acquires
                // some lock keys and dies without releasing them. Lock keys expire after a few minutes.
-               $rounds = 0;
-               $start = microtime( true );
-               do {
-                       if ( ( ++$rounds % 4 ) == 0 ) {
-                               usleep( 1000 * 50 ); // 50 ms
-                       }
-                       foreach ( array_diff( $keys, $lockedKeys ) as $key ) {
-                               if ( $memc->add( "$key:mutex", 1, 180 ) ) { // lock record
-                                       $lockedKeys[] = $key;
-                               } else {
-                                       continue; // acquire in order
+               $loop = new WaitConditionLoop(
+                       function () use ( $memc, $keys, &$lockedKeys ) {
+                               foreach ( array_diff( $keys, $lockedKeys ) as $key ) {
+                                       if ( $memc->add( "$key:mutex", 1, 180 ) ) { // lock record
+                                               $lockedKeys[] = $key;
+                                       }
                                }
-                       }
-               } while ( count( $lockedKeys ) < count( $keys ) && ( microtime( true ) - $start ) <= 3 );
+
+                               return array_diff( $keys, $lockedKeys )
+                                       ? WaitConditionLoop::CONDITION_CONTINUE
+                                       : true;
+                       },
+                       3.0 // timeout
+               );
+               $loop->invoke();
 
                if ( count( $lockedKeys ) != count( $keys ) ) {
                        $this->releaseMutexes( $memc, $lockedKeys ); // failed; release what was locked
@@ -376,8 +378,8 @@ class MemcLockManager extends QuorumLockManager {
        function __destruct() {
                while ( count( $this->locksHeld ) ) {
                        foreach ( $this->locksHeld as $path => $locks ) {
-                               $this->doUnlock( array( $path ), self::LOCK_EX );
-                               $this->doUnlock( array( $path ), self::LOCK_SH );
+                               $this->doUnlock( [ $path ], self::LOCK_EX );
+                               $this->doUnlock( [ $path ], self::LOCK_SH );
                        }
                }
        }