Manuel Jacob <me@manueljacob.de> [Tue, 19 Nov 2019 11:59:43 +0100] rev 43710
py3: use pycompat.bytestr() instead of pycompat.sysstr()
pycompat.sysstr() doesn’t work because it doesn’t accept arguments of type
`type` and returns a unicode object on Python3, while the format string wants
a bytes-like object.
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com> [Mon, 18 Nov 2019 20:10:38 -0800] rev 43709
lock: fix race in lock-breaking code
With low frequency, I see hg pulls fail with output like:
abort: no such file or directory: .hg/store/lock
I think what happens is, in lock.py, in:
def _testlock(self, locker):
if not self._lockshouldbebroken(locker):
return locker
# if locker dead, break lock. must do this with another lock
# held, or can race and break valid lock.
try:
with lock(self.vfs, self.f + b'.break', timeout=0):
self.vfs.unlink(self.f)
except error.LockError:
return locker
if a lock is breakable on disk, and two hg processes concurrently get
to the "if locker dead" comment, a possible interleaving is: process1
finishes executing the function and then process2 finishes executing
the function. If that happens, process2 will either get ENOENT in
self.vfs.unlink (resulting in the spurious failure above), or break a
valid lock and potentially cause repository corruption.
The fix is simple enough: make sure the lock is breakable _inside_ the
critical section, because only then can we know that no other process
can invalidate our knowledge on the lock on disk.
I don't think there are tests for this. I've tested this manually
with:
diff --git a/mercurial/lock.py b/mercurial/lock.py
--- a/mercurial/lock.py
+++ b/mercurial/lock.py
@@ -351,6 +351,8 @@ class lock(object):
if not self._lockshouldbebroken(locker):
return locker
+ import random
+ time.sleep(1. + random.random())
# if locker dead, break lock. must do this with another lock
# held, or can race and break valid lock.
try:
@@ -358,6 +360,7 @@ class lock(object):
self.vfs.unlink(self.f)
except error.LockError:
return locker
+ time.sleep(1)
def testlock(self):
"""return id of locker if lock is valid, else None.
and I see this change of behavior before/after this commit:
$ $hg init repo
$ cd repo
$ ln -s $HOSTNAME/effffffc:987654321 .hg/wlock
$ touch a
$ $hg commit -Am_ & $hg commit -Am _; wait
-abort: No such file or directory: '/tmp/repo/.hg/wlock'
adding a
+warning: ignoring unknown working parent 679a8959a8ca!
+nothing changed
Differential Revision: https://phab.mercurial-scm.org/D7199
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com> [Fri, 01 Nov 2019 19:59:07 -0400] rev 43708
lock: refactor in preparation for next commit
Differential Revision: https://phab.mercurial-scm.org/D7198
Augie Fackler <augie@google.com> [Fri, 15 Nov 2019 11:30:33 -0500] rev 43707
extensions: suppress a pytype failure due to a typeshed bug
Bug filed upstream, suppress the failure here so we can move on.
Differential Revision: https://phab.mercurial-scm.org/D7410
Augie Fackler <augie@google.com> [Thu, 14 Nov 2019 15:49:21 -0500] rev 43706
dispatch: add some assertions to give pytype a helping hand
Differential Revision: https://phab.mercurial-scm.org/D7409
Augie Fackler <augie@google.com> [Thu, 14 Nov 2019 15:49:01 -0500] rev 43705
extensions: hide two confusing import statements from pytype
Differential Revision: https://phab.mercurial-scm.org/D7408
Augie Fackler <augie@google.com> [Thu, 14 Nov 2019 13:27:57 -0500] rev 43704
debugcommands: add assertions to convince pytype peer is not None
This function is moderately annoyingly defined, and peer is set up iff we're
not in raw-proto mode. That's fine, but it confuses pytype. Adding these
assertions is a low-overhead way to convince pytype we're doing reasonable
things.
Differential Revision: https://phab.mercurial-scm.org/D7407
Augie Fackler <augie@google.com> [Wed, 13 Nov 2019 22:35:15 -0500] rev 43703
debugcommands: suppress import errors for pytype
Differential Revision: https://phab.mercurial-scm.org/D7385
Augie Fackler <augie@google.com> [Wed, 13 Nov 2019 22:22:49 -0500] rev 43702
state: add a pytype annotation
Differential Revision: https://phab.mercurial-scm.org/D7383
Augie Fackler <augie@google.com> [Wed, 13 Nov 2019 22:22:31 -0500] rev 43701
logcmdutil: add a type annotation
This wasn't actually required in the end, as there was a real bug
found by pytype, but the annotation helped me figure that out. We can
drop this patch if that's the preference.
Differential Revision: https://phab.mercurial-scm.org/D7382