Patchwork [6,of,6,V2,RFC] localrepo: properly lock full shared repositories

login
register
mail settings
Submitter Angel Ezquerra
Date Dec. 26, 2014, 11:46 a.m.
Message ID <a91f8c828f4e4f018304.1419594414@108.1.168.192.in-addr.arpa>
Download mbox | patch
Permalink /patch/7247/
State Changes Requested
Headers show

Comments

Angel Ezquerra - Dec. 26, 2014, 11:46 a.m.
# HG changeset patch
# User Angel Ezquerra <angel.ezquerra@gmail.com>
# Date 1419377236 -3600
#      Wed Dec 24 00:27:16 2014 +0100
# Node ID a91f8c828f4e4f01830416abf2b5641cfcd88b10
# Parent  bb70464b9121df236db6d264d57b6f56ad78cd3b
localrepo: properly lock full shared repositories

Since the "non-store" parts of a full share repository is split between the
source repository (which contains most of the repository files) and the shared
repository itself (which contains the dirstate, bookmarks.current and a few
other minor files), we must lock both repositories when locking the shared
repository. This is done by using a multilock that holds two locks, the source
repository wlock and shared repository wlock.

# Notes:

- In the final version of this patch series this revision must be folded into the
revision that introduces the "full share" support, but I want to be able to
discuss this part individually.
- This is the last revision in the series. I ran the test suite and all tests
pass.

Patch

diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -273,11 +273,12 @@ 
                 # the source repository
                 self.origpath = self.path
                 self.path = self.sharedpath
+                self.localvfs = self.vfs
                 def selectfn(path):
                     if path in fullshareexceptions:
                         return 1
                     return 0
-                self.vfs = scmutil.unionvfs(selectfn, sourcevfs, self.vfs)
+                self.vfs = scmutil.unionvfs(selectfn, sourcevfs, self.localvfs)
                 self.opener = self.vfs
         except IOError, inst:
             if inst.errno != errno.ENOENT:
@@ -1165,7 +1166,16 @@ 
 
             self._filecache['dirstate'].refresh()
 
-        l = self._lock(self.vfs, "wlock", wait, unlock,
+        if self.fullshare:
+            sourcelock = self._lock(self.vfs, "wlock", wait, None,
+                       self.invalidatedirstate, _('share source %s') %
+                       self.origroot)
+            locallock = self._lock(self.localvfs, "wlock", wait, unlock,
+                       self.invalidatedirstate, _('working directory of %s') %
+                       self.origroot)
+            l = lockmod.multilock(locallock, sourcelock)
+        else:
+            l = self._lock(self.vfs, "wlock", wait, unlock,
                        self.invalidatedirstate, _('working directory of %s') %
                        self.origroot)
         self._wlockref = weakref.ref(l)