Patchwork [01,of,11] util: debugstacktrace, flush before and after writing

login
register
mail settings
Submitter Mads Kiilerich
Date Feb. 20, 2014, 1:43 a.m.
Message ID <94a0e47043f2a95a5dea.1392860605@localhost.localdomain>
Download mbox | patch
Permalink /patch/3707/
State Accepted
Commit be27652675ceca35e4b413ef1b35aac562a876f5
Headers show

Comments

Mads Kiilerich - Feb. 20, 2014, 1:43 a.m.
# HG changeset patch
# User Mads Kiilerich <madski@unity3d.com>
# Date 1392860316 -3600
#      Thu Feb 20 02:38:36 2014 +0100
# Node ID 94a0e47043f2a95a5dea81303c9f34b85090bdb2
# Parent  87e52e6425625ea4f7645cfe2fc491a21f9a6b51
util: debugstacktrace, flush before and after writing

Close another stream (default stdout, which often is buffered) before writing
to the primary stream (default stderr, which often is unbuffered). The primary
stream is also flushed after writing (in case it is buffered).

This fixes non-deterministic output order, especially on windows.

Patch

diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -1989,12 +1989,14 @@  class hooks(object):
         for source, hook in self._hooks:
             hook(*args)
 
-def debugstacktrace(msg='stacktrace', skip=0, f=sys.stderr):
+def debugstacktrace(msg='stacktrace', skip=0, f=sys.stderr, otherf=sys.stdout):
     '''Writes a message to f (stderr) with a nicely formatted stacktrace.
-    Skips the 'skip' last entries.
+    Skips the 'skip' last entries. By default it will flush stdout first.
     It can be used everywhere and do intentionally not require an ui object.
     Not be used in production code but very convenient while developing.
     '''
+    if otherf:
+        otherf.flush()
     f.write('%s at:\n' % msg)
     entries = [('%s:%s' % (fn, ln), func)
         for fn, ln, func, _text in traceback.extract_stack()[:-skip - 1]]
@@ -2002,6 +2004,7 @@  def debugstacktrace(msg='stacktrace', sk
         fnmax = max(len(entry[0]) for entry in entries)
         for fnln, func in entries:
             f.write(' %-*s in %s\n' % (fnmax, fnln, func))
+    f.flush()
 
 # convenient shortcut
 dst = debugstacktrace