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

login
register
mail settings
Submitter Yuya Nishihara
Date May 23, 2018, 2:46 p.m.
Message ID <d99bba4101af58e3e83d.1527086770@mimosa>
Download mbox | patch
Permalink /patch/31823/
State Accepted
Headers show

Comments

Yuya Nishihara - May 23, 2018, 2:46 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@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.
Gregory Szorc - May 24, 2018, 1 a.m.
On Wed, May 23, 2018 at 7:46 AM, Yuya Nishihara <yuya@tcha.org> wrote:

> # HG changeset patch
> # User Yuya Nishihara <yuya@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
>

Queued for stable.


>
> 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:
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
>

Patch

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: