[PATCH 1 of 2 STABLE] lock: add internal config to not replace signal handlers while locking

Yuya Nishihara yuya at tcha.org
Wed May 23 14:46:10 UTC 2018


# HG changeset patch
# User Yuya Nishihara <yuya at tcha.org>
# Date 1526646246 -32400
#      Fri May 18 21:24:06 2018 +0900
# Branch stable
# Node ID d99bba4101af58e3e83dab60b644bb687794e6d9
# Parent  d46a38c07b1a2ba451e22e57aa22fd1308f2046f
lock: add internal config to not replace signal handlers while locking

signal.signal() is blocked in some WSGI environments, and a horrible warning
is sent to the server log. So we need a way to disable it, and I think
abusing ui.config is the simplest workaround.

diff --git a/mercurial/configitems.py b/mercurial/configitems.py
--- a/mercurial/configitems.py
+++ b/mercurial/configitems.py
@@ -1127,6 +1127,9 @@ coreconfigitem('ui', 'report_untrusted',
 coreconfigitem('ui', 'rollback',
     default=True,
 )
+coreconfigitem('ui', 'signal-safe-lock',
+    default=True,
+)
 coreconfigitem('ui', 'slash',
     default=False,
 )
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1693,12 +1693,15 @@ class localrepository(object):
         if wait:
             timeout = self.ui.configint("ui", "timeout")
             warntimeout = self.ui.configint("ui", "timeout.warn")
+        # internal config: ui.signal-safe-lock
+        signalsafe = self.ui.configbool('ui', 'signal-safe-lock')
 
         l = lockmod.trylock(self.ui, vfs, lockname, timeout, warntimeout,
                             releasefn=releasefn,
                             acquirefn=acquirefn, desc=desc,
                             inheritchecker=inheritchecker,
-                            parentlock=parentlock)
+                            parentlock=parentlock,
+                            signalsafe=signalsafe)
         return l
 
     def _afterlock(self, callback):
diff --git a/mercurial/lock.py b/mercurial/lock.py
--- a/mercurial/lock.py
+++ b/mercurial/lock.py
@@ -21,6 +21,7 @@ from . import (
     encoding,
     error,
     pycompat,
+    util,
 )
 
 from .utils import (
@@ -177,7 +178,7 @@ class lock(object):
 
     def __init__(self, vfs, fname, timeout=-1, releasefn=None, acquirefn=None,
                  desc=None, inheritchecker=None, parentlock=None,
-                 dolock=True):
+                 signalsafe=True, dolock=True):
         self.vfs = vfs
         self.f = fname
         self.held = 0
@@ -189,6 +190,10 @@ class lock(object):
         self.parentlock = parentlock
         self._parentheld = False
         self._inherited = False
+        if signalsafe:
+            self._maybedelayedinterrupt = _delayedinterrupt
+        else:
+            self._maybedelayedinterrupt = util.nullcontextmanager
         self.postrelease  = []
         self.pid = self._getpid()
         if dolock:
@@ -244,7 +249,7 @@ class lock(object):
         while not self.held and retry:
             retry -= 1
             try:
-                with _delayedinterrupt():
+                with self._maybedelayedinterrupt():
                     self.vfs.makelock(lockname, self.f)
                     self.held = 1
             except (OSError, IOError) as why:


More information about the Mercurial-devel mailing list