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