From adedb662790fb2768d9d258dc1c7a44ac85b49b4 Mon Sep 17 00:00:00 2001 From: Aaron Schulz Date: Sat, 28 Apr 2012 12:49:46 -0700 Subject: [PATCH] [FileBackend] Added getScopedLocksForOps() function. This lets callers safely change files *and* update DB data. Change-Id: I6ec70e98b1535528b756e109b8b28e4a3e839552 --- includes/filerepo/backend/FileBackend.php | 18 ++++++++++++++++++ .../filerepo/backend/FileBackendMultiWrite.php | 16 ++++++++++++++++ includes/filerepo/backend/FileBackendStore.php | 12 ++++++++++++ 3 files changed, 46 insertions(+) diff --git a/includes/filerepo/backend/FileBackend.php b/includes/filerepo/backend/FileBackend.php index 544c9c28dc..59ca04d43a 100644 --- a/includes/filerepo/backend/FileBackend.php +++ b/includes/filerepo/backend/FileBackend.php @@ -682,6 +682,24 @@ abstract class FileBackend { return ScopedLock::factory( $this->lockManager, $paths, $type, $status ); } + /** + * Get an array of scoped locks needed for a batch of file operations. + * + * Normally, FileBackend::doOperations() handles locking, unless + * the 'nonLocking' param is passed in. This function is useful if you + * want the files to be locked for a broader scope than just when the + * files are changing. For example, if you need to update DB metadata, + * you may want to keep the files locked until finished. + * + * @see FileBackend::doOperations() + * + * @param $ops Array List of file operations to FileBackend::doOperations() + * @param $status Status Status to update on lock/unlock + * @return Array List of ScopedFileLocks or null values + * @since 1.20 + */ + abstract public function getScopedLocksForOps( array $ops, Status $status ); + /** * Get the root storage path of this backend. * All container paths are "subdirectories" of this path. diff --git a/includes/filerepo/backend/FileBackendMultiWrite.php b/includes/filerepo/backend/FileBackendMultiWrite.php index 208d34b6ad..7f2c5b7b37 100644 --- a/includes/filerepo/backend/FileBackendMultiWrite.php +++ b/includes/filerepo/backend/FileBackendMultiWrite.php @@ -434,4 +434,20 @@ class FileBackendMultiWrite extends FileBackend { $backend->clearCache( $realPaths ); } } + + /** + * @see FileBackend::getScopedLocksForOps() + */ + public function getScopedLocksForOps( array $ops, Status $status ) { + $fileOps = $this->backends[$this->masterIndex]->getOperationsInternal( $ops ); + // Get the paths to lock from the master backend + $paths = $this->backends[$this->masterIndex]->getPathsToLockForOpsInternal( $fileOps ); + // Get the paths under the proxy backend's name + $paths['sh'] = $this->unsubstPaths( $paths['sh'] ); + $paths['ex'] = $this->unsubstPaths( $paths['ex'] ); + return array( + $this->getScopedFileLocks( $paths['sh'], LockManager::LOCK_UW, $status ), + $this->getScopedFileLocks( $paths['ex'], LockManager::LOCK_EX, $status ) + ); + } } diff --git a/includes/filerepo/backend/FileBackendStore.php b/includes/filerepo/backend/FileBackendStore.php index fab62e5bd2..d091da91e5 100644 --- a/includes/filerepo/backend/FileBackendStore.php +++ b/includes/filerepo/backend/FileBackendStore.php @@ -856,6 +856,18 @@ abstract class FileBackendStore extends FileBackend { return $paths; } + /** + * @see FileBackend::getScopedLocksForOps() + * @return Array + */ + public function getScopedLocksForOps( array $ops, Status $status ) { + $paths = $this->getPathsToLockForOpsInternal( $this->getOperationsInternal( $ops ) ); + return array( + $this->getScopedFileLocks( $paths['sh'], LockManager::LOCK_UW, $status ), + $this->getScopedFileLocks( $paths['ex'], LockManager::LOCK_EX, $status ) + ); + } + /** * @see FileBackend::doOperationsInternal() * @return Status -- 2.20.1