# HG changeset patch # User Benoit Boissinot # Date 1131752053 28800 # Node ID 2ba8bf7defda2a547678a195b7a1c3a2e9be7ac4 # Parent abfab59fce790a3cc49f4cfa8a42884db2057116 add localrepo.wlock for protecting the dirstate - add localrepo.wlock - nest it in localrepo.lock - protect the code that change the dirstate diff -r abfab59fce79 -r 2ba8bf7defda mercurial/localrepo.py --- a/mercurial/localrepo.py Fri Nov 11 15:34:09 2005 -0800 +++ b/mercurial/localrepo.py Fri Nov 11 15:34:13 2005 -0800 @@ -232,13 +232,13 @@ return False def undo(self): + wlock = self.wlock() lock = self.lock() if os.path.exists(self.join("undo")): self.ui.status(_("rolling back last transaction\n")) transaction.rollback(self.opener, self.join("undo")) - self.dirstate = None util.rename(self.join("undo.dirstate"), self.join("dirstate")) - self.dirstate = dirstate.dirstate(self.opener, self.ui, self.root) + self.dirstate.read() else: self.ui.warn(_("no undo information available\n")) @@ -251,6 +251,17 @@ return lock.lock(self.join("lock"), wait) raise inst + def wlock(self, wait=1): + try: + wlock = lock.lock(self.join("wlock"), 0, self.dirstate.write) + except lock.LockHeld, inst: + if not wait: + raise inst + self.ui.warn(_("waiting for lock held by %s\n") % inst.args[0]) + wlock = lock.lock(self.join("wlock"), wait, self.dirstate.write) + self.dirstate.read() + return wlock + def rawcommit(self, files, text, user, date, p1=None, p2=None): orig_parent = self.dirstate.parents()[0] or nullid p1 = p1 or self.dirstate.parents()[0] or nullid @@ -267,6 +278,8 @@ else: update_dirstate = 0 + wlock = self.wlock() + lock = self.lock() tr = self.transaction() mm = m1.copy() mfm = mf1.copy() @@ -355,6 +368,7 @@ if not self.hook("precommit"): return None + wlock = self.wlock() lock = self.lock() tr = self.transaction() @@ -526,6 +540,7 @@ return (c, a, d, u) def add(self, list): + wlock = self.wlock() for f in list: p = self.wjoin(f) if not os.path.exists(p): @@ -538,6 +553,7 @@ self.dirstate.update([f], "a") def forget(self, list): + wlock = self.wlock() for f in list: if self.dirstate.state(f) not in 'ai': self.ui.warn(_("%s not added!\n") % f) @@ -551,6 +567,7 @@ util.unlink(self.wjoin(f)) except OSError, inst: if inst.errno != errno.ENOENT: raise + wlock = self.wlock() for f in list: p = self.wjoin(f) if os.path.exists(p): @@ -568,6 +585,7 @@ mn = self.changelog.read(p)[0] mf = self.manifest.readflags(mn) m = self.manifest.read(mn) + wlock = self.wlock() for f in list: if self.dirstate.state(f) not in "r": self.ui.warn("%s not removed!\n" % f) @@ -584,6 +602,7 @@ elif not os.path.isfile(p): self.ui.warn(_("copy failed: %s is not a file\n") % dest) else: + wlock = self.wlock() if self.dirstate.state(dest) == '?': self.dirstate.update([dest], "a") self.dirstate.copy(source, dest) @@ -1374,6 +1393,9 @@ mw[f] = "" mfw[f] = util.is_exec(self.wjoin(f), mfw.get(f, False)) + if moddirstate: + wlock = self.wlock() + for f in d: if f in mw: del mw[f]