[PATCH 1 of 3 v3] profiling: allow nested usage of profile context manager
Arun Kulshreshtha
kulshrax at fb.com
Tue Sep 20 20:35:20 UTC 2016
# HG changeset patch
# User Arun Kulshreshtha <kulshrax at fb.com>
# Date 1474402733 25200
# Tue Sep 20 13:18:53 2016 -0700
# Node ID 69499ec91691f952a8a28092c361a0e3daccc429
# Parent 285a8c3e53f2183438f0cdbc238e4ab851d0d110
profiling: allow nested usage of profile context manager
Add a check to the profile context manager to ensure that profiling
is only enabled once in nested invocations of this context manager.
The flag to guard against nesting is stored in thead-local storage,
so this only prevents nested usage within the same thread. (i.e.,
if a thread is spawned while profiling is active, the child thread
is also able to enable profiling.)
diff --git a/mercurial/profiling.py b/mercurial/profiling.py
--- a/mercurial/profiling.py
+++ b/mercurial/profiling.py
@@ -10,6 +10,7 @@
import contextlib
import os
import sys
+import threading
import time
from .i18n import _
@@ -108,6 +109,22 @@
Profiling is active when the context manager is active. When the context
manager exits, profiling results will be written to the configured output.
"""
+
+ # Initialize thread-local storage for profiling.
+ if not util.safehasattr(profile, 'threadlocal'):
+ profile.threadlocal = threading.local()
+
+ # Flag attribute will be re-initialized in each new thread.
+ if not util.safehasattr(profile.threadlocal, 'started'):
+ profile.threadlocal.started = False
+
+ # Guard against nested invocations of this context manager within
+ # the same thread. Only the outermost invocation will run.
+ if profile.threadlocal.started:
+ yield
+ return
+ profile.threadlocal.started = True
+
profiler = os.getenv('HGPROF')
if profiler is None:
profiler = ui.config('profiling', 'type', default='ls')
@@ -145,6 +162,7 @@
val = val.replace('%', '%%')
ui.log('profile', val)
fp.close()
+ profile.threadlocal.started = False
@contextlib.contextmanager
def maybeprofile(ui):
More information about the Mercurial-devel
mailing list