diff options
author | bradnelson@chromium.org <bradnelson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-12-04 19:35:47 +0000 |
---|---|---|
committer | bradnelson@chromium.org <bradnelson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-12-04 19:35:47 +0000 |
commit | 5a17959168f700202c3ee498e88cca7bcfa43a97 (patch) | |
tree | f0c8d497ded5551516310cebec76c3395880c19c /site_scons/site_tools/defer.py | |
parent | aedd85af7d7d0c90ed343ece4c66660db00841ec (diff) | |
download | chromium_src-5a17959168f700202c3ee498e88cca7bcfa43a97.zip chromium_src-5a17959168f700202c3ee498e88cca7bcfa43a97.tar.gz chromium_src-5a17959168f700202c3ee498e88cca7bcfa43a97.tar.bz2 |
Pulling in hammer changes.
Review URL: http://codereview.chromium.org/13134
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@6370 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'site_scons/site_tools/defer.py')
-rw-r--r-- | site_scons/site_tools/defer.py | 71 |
1 files changed, 54 insertions, 17 deletions
diff --git a/site_scons/site_tools/defer.py b/site_scons/site_tools/defer.py index 8b6de89..3da09ea 100644 --- a/site_scons/site_tools/defer.py +++ b/site_scons/site_tools/defer.py @@ -37,6 +37,11 @@ import types import SCons.Errors +# Current group name being executed by ExecuteDefer(). Set to None outside +# of ExecuteDefer(). +_execute_defer_context = None + + class DeferGroup: """Named list of functions to be deferred.""" # If we derive DeferGroup from object, instances of it return type @@ -127,6 +132,11 @@ def ExecuteDefer(self): Args: self: Current environment context. """ + # Check for re-entrancy + global _execute_defer_context + if _execute_defer_context: + raise SCons.Errors.UserError('Re-entrant call to ExecuteDefer().') + # Save directory, so SConscript functions can occur in the right subdirs oldcwd = os.getcwd() @@ -141,24 +151,39 @@ def ExecuteDefer(self): defer_groups = GetDeferGroups(self) # Loop through deferred functions - while defer_groups: - did_work = False - for name, group in defer_groups.items(): - if group.after.intersection(defer_groups.keys()): - continue # Still have dependencies - if group.func_env_cwd: - # Run all the functions in our named group - for func, env, cwd in group.func_env_cwd: - os.chdir(cwd) - func(env) - did_work = True - del defer_groups[name] - break - if not did_work: - errmsg = 'Error in ExecuteDefer: dependency cycle detected.\n' + try: + while defer_groups: + did_work = False for name, group in defer_groups.items(): - errmsg += ' %s after: %s\n' % (name, group.after) - raise SCons.Errors.UserError(errmsg) + if group.after.intersection(defer_groups.keys()): + continue # Still have dependencies + + # Set defer context + _execute_defer_context = name + + # Remove this group from the list of defer groups now, in case one of + # the functions it calls adds back a function into that defer group. + del defer_groups[name] + + if group.func_env_cwd: + # Run all the functions in our named group + for func, env, cwd in group.func_env_cwd: + os.chdir(cwd) + func(env) + + # The defer groups have been altered, so restart the search for + # functions that can be executed. + did_work = True + break + + if not did_work: + errmsg = 'Error in ExecuteDefer: dependency cycle detected.\n' + for name, group in defer_groups.items(): + errmsg += ' %s after: %s\n' % (name, group.after) + raise SCons.Errors.UserError(errmsg) + finally: + # No longer in a defer context + _execute_defer_context = None # Restore directory os.chdir(oldcwd) @@ -272,6 +297,18 @@ def Defer(self, *args, **kwargs): # Add dependencies for the function group.after.update(after) + # If we are already inside a call to ExecuteDefer(), any functions which are + # deferring until after the current function must also be deferred until + # after this new function. In short, this means that if b() defers until + # after a() and a() calls Defer() to defer c(), then b() must also defer + # until after c(). + if _execute_defer_context and name != _execute_defer_context: + for other_name, other_group in GetDeferGroups(self).items(): + if other_name == name: + continue # Don't defer after ourselves + if _execute_defer_context in other_group.after: + other_group.after.add(name) + def generate(env): # NOTE: SCons requires the use of this name, which fails gpylint. |