https://www.mediawiki.org/wiki/Special:Code/MediaWiki/104204

Revision: 104204
Author:   aaron
Date:     2011-11-24 22:50:41 +0000 (Thu, 24 Nov 2011)
Log Message:
-----------
* Fixed EX locks in DBFileLockManager after testing (FOR UPDATE doesn't set the 
needed gap locks)
* Fixes to FSFileLockManager after testing
* Factored out FSFileLockManager::getLockPath() function

Modified Paths:
--------------
    branches/FileBackend/phase3/includes/filerepo/backend/FileLockManager.php

Modified: 
branches/FileBackend/phase3/includes/filerepo/backend/FileLockManager.php
===================================================================
--- branches/FileBackend/phase3/includes/filerepo/backend/FileLockManager.php   
2011-11-24 22:46:02 UTC (rev 104203)
+++ branches/FileBackend/phase3/includes/filerepo/backend/FileLockManager.php   
2011-11-24 22:50:41 UTC (rev 104204)
@@ -77,7 +77,7 @@
        protected $handles = array();
 
        function __construct( array $config ) {
-               $this->lockDir = $config['lockDir'];
+               $this->lockDir = $config['lockDirectory'];
        }
 
        function doLock( array $keys, $type ) {
@@ -129,18 +129,18 @@
                        $status->warning( 'lockmanager-alreadylocked', $key );
                } else {
                        wfSuppressWarnings();
-                       $handle = fopen( "{$this->lockDir}/{$key}", 'c' );
+                       $handle = fopen( $this->getLockPath( $key ), 'c' );
                        wfRestoreWarnings();
                        if ( !$handle ) { // lock dir missing?
-                               wfMkdirParents( "{$this->lockDir}/{$key}" );
+                               wfMkdirParents( $this->lockDir );
                                wfSuppressWarnings();
-                               $handle = fopen( "{$this->lockDir}/{$key}", 'c' 
); // try again
+                               $handle = fopen( $this->getLockPath( $key ), 
'c' ); // try again
                                wfRestoreWarnings();
                        }
                        if ( $handle ) {
                                // Either a shared or exclusive lock
                                $lock = ( $type == self::LOCK_SH ) ? LOCK_SH : 
LOCK_EX;
-                               if ( flock( $handle, $lock ) ) {
+                               if ( flock( $handle, $lock | LOCK_NB ) ) {
                                        $this->handles[$key][$type] = $handle;
                                } else {
                                        fclose( $handle );
@@ -186,16 +186,26 @@
                        if ( !count( $this->handles[$key] ) ) {
                                wfSuppressWarnings();
                                # No locks are held for the lock file anymore
-                               if ( !unlink( "{$this->lockDir}/{$key}" ) ) {
+                               if ( !unlink( $this->getLockPath( $key ) ) ) {
                                        $status->warning( 
'lockmanager-fail-deletelock', $key );
                                }
                                wfRestoreWarnings();
+                               unset( $this->handles[$key] );
                        }
                }
 
                return $status;
        }
 
+       /**
+        * Get the path to the lock file for a key
+        * @param $key string
+        * @return string
+        */
+       protected function getLockPath( $key ) {
+               return "{$this->lockDir}/{$key}.lock";
+       }
+
        function __destruct() {
                // Make sure remaining files get cleared for sanity
                foreach ( $this->handles as $key => $locks ) {
@@ -203,7 +213,7 @@
                                flock( $handle, LOCK_UN ); // PHP 5.3 will not 
do this automatically
                                fclose( $handle );
                        }
-                       unlink( "{$this->lockDir}/{$key}" );
+                       unlink( $this->getLockPath( $key ) );
                }
        }
 }
@@ -388,17 +398,21 @@
                        }
                        $this->activeConns[$server]->setSessionOptions( 
$options );
                }
+               $db = $this->activeConns[$server];
                # Try to get the locks...this should be the last query of this 
function
-               $lockingClause = ( $type == self::LOCK_SH )
-                       ? 'LOCK IN SHARE MODE' // reader lock
-                       : 'FOR UPDATE'; // writer lock
-               $this->activeConns[$server]->select(
-                       'file_locking',
-                       '1',
-                       array( 'fl_key' => $keys ),
-                       __METHOD__,
-                       array( $lockingClause )
-               );
+               if ( $type == self::LOCK_SH ) { // reader locks
+                       $db->select( 'file_locking', '1',
+                               array( 'fl_key' => $keys ),
+                               __METHOD__,
+                               array( 'LOCK IN SHARE MODE' ) // single-row gap 
locks
+                       );
+               } else { // writer locks
+                       $data = array();
+                       foreach ( $keys as $key ) {
+                               $data[] = array( 'fl_key' => $key );
+                       }
+                       $db->insert( 'file_locking', $data, __METHOD__ ); // 
error on duplicate
+               }
        }
 
        /**
@@ -441,7 +455,7 @@
        protected function commitLockTransactions() {
                foreach ( $this->activeConns as $server => $db ) {
                        try {
-                               $db->commit(); // finish transaction
+                               $db->rollback(); // finish transaction and kill 
any rows
                        } catch ( DBError $e ) {
                                // oh well; best effort
                        }


_______________________________________________
MediaWiki-CVS mailing list
MediaWiki-CVS@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to