Patchwork [2,of,2,STABLE] hgweb: do not try to replace signal handlers while locking

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

Comments

Yuya Nishihara - May 23, 2018, 2:46 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1526646725 -32400
#      Fri May 18 21:32:05 2018 +0900
# Branch stable
# Node ID 4c0f3860696a150ad71d58ac9fdebe58963b9c64
# Parent  d99bba4101af58e3e83dab60b644bb687794e6d9
hgweb: do not try to replace signal handlers while locking

According to the issue 5889, mod_wsgi issues a warning on signal.signal()
call, and we wouldn't want to see it in error log. The problem addressed
by d77c3b023393 could potentially occur in web session, but that would be
less likely than in user processes.

Patch

diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py
--- a/mercurial/hgweb/hgweb_mod.py
+++ b/mercurial/hgweb/hgweb_mod.py
@@ -225,6 +225,12 @@  class hgweb(object):
         # resolve file patterns relative to repo root
         r.ui.setconfig('ui', 'forcecwd', r.root, 'hgweb')
         r.baseui.setconfig('ui', 'forcecwd', r.root, 'hgweb')
+        # it's unlikely that we can replace signal handlers in WSGI server,
+        # and mod_wsgi issues a big warning. a plain hgweb process (with no
+        # threading) could replace signal handlers, but we don't bother
+        # conditionally enabling it.
+        r.ui.setconfig('ui', 'signal-safe-lock', 'false', 'hgweb')
+        r.baseui.setconfig('ui', 'signal-safe-lock', 'false', 'hgweb')
         # displaying bundling progress bar while serving feel wrong and may
         # break some wsgi implementation.
         r.ui.setconfig('progress', 'disable', 'true', 'hgweb')
diff --git a/tests/test-hgweb.t b/tests/test-hgweb.t
--- a/tests/test-hgweb.t
+++ b/tests/test-hgweb.t
@@ -841,13 +841,59 @@  no style can be loaded from directories 
   
   fall back to default
 
+  $ killdaemons.py
+
+Test signal-safe-lock in web and non-web processes
+
+  $ cat <<'EOF' > disablesig.py
+  > import signal
+  > from mercurial import error, extensions
+  > def disabledsig(orig, signalnum, handler):
+  >     if signalnum == signal.SIGTERM:
+  >         raise error.Abort(b'SIGTERM cannot be replaced')
+  >     try:
+  >         return orig(signalnum, handler)
+  >     except ValueError:
+  >         raise error.Abort(b'signal.signal() called in thread?')
+  > def uisetup(ui):
+  >    extensions.wrapfunction(signal, b'signal', disabledsig)
+  > EOF
+
+ by default, signal interrupt should be disabled while making a lock file
+
+  $ hg debuglock -s --config extensions.disablesig=disablesig.py
+  abort: SIGTERM cannot be replaced
+  [255]
+
+ but in hgweb, it isn't disabled since some WSGI servers complains about
+ unsupported signal.signal() calls (see issue5889)
+
+  $ hg serve --config extensions.disablesig=disablesig.py \
+  > --config web.allow-push='*' --config web.push_ssl=False \
+  > -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
+  $ cat hg.pid >> $DAEMON_PIDS
+
+  $ hg clone -q http://localhost:$HGPORT/ repo
+  $ hg bookmark -R repo foo
+
+ push would fail if signal.signal() were called
+
+  $ hg push -R repo -B foo
+  pushing to http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  exporting bookmark foo
+  [1]
+
+  $ rm -R repo
+  $ killdaemons.py
+
 errors
 
   $ cat errors.log
 
 Uncaught exceptions result in a logged error and canned HTTP response
 
-  $ killdaemons.py
   $ hg serve --config extensions.hgweberror=$TESTDIR/hgweberror.py -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
   $ cat hg.pid >> $DAEMON_PIDS