[PATCH STABLE] extensions: clear aftercallbacks after execution (issue4646)

Gregory Szorc gregory.szorc at gmail.com
Tue May 5 23:35:25 CDT 2015

# HG changeset patch
# User Gregory Szorc <gregory.szorc at gmail.com>
# Date 1430886916 25200
#      Tue May 05 21:35:16 2015 -0700
# Branch stable
# Node ID 4da7e74074010404744171ad68c1a1bd7d100696
# Parent  41cd8171e58f991373dcd0b4897dc1e5978d42dd
extensions: clear aftercallbacks after execution (issue4646)

It was reported that enabling pager without color could cause a hang.
Inserting print statements revealed that the callbacks in
extensions._aftercallbacks were being invoked twice.

I'm not sure exactly how the hang comes to be. But, clearing
extensions._aftercallbacks makes the problem go away. This presumably
has something to do with forked processes inheriting
extensions._aftercallbacks and that somehow results in badness.

The reproduce steps in the bug seem to only occur when the output of
a command is less than the size of the current screen. This is not
something that can easily be tested. I verified the test case works
with this patch and that pager and color interaction continues to
work. Since we have no existing automated tests for pager, this sadly
appears to be the best I can do.

diff --git a/mercurial/extensions.py b/mercurial/extensions.py
--- a/mercurial/extensions.py
+++ b/mercurial/extensions.py
@@ -133,8 +133,12 @@ def loadall(ui):
         for fn in _aftercallbacks[shortname]:
+    # Forked processes appear to inherit _aftercallbacks, which may cause
+    # deadlock. See issue4646.
+    _aftercallbacks.clear()
 def afterloaded(extension, callback):
     '''Run the specified function after a named extension is loaded.
     If the named extension is already loaded, the callback will be called

More information about the Mercurial-devel mailing list