author | Mike Shal <mshal@mozilla.com> |
Fri, 20 Jun 2014 11:35:25 -0400 | |
changeset 189902 | a6b5b538815561ac3acdb37a3575a64e35c2ee8f |
parent 189901 | 26b95471c5f8f41dfcb207c9358ae70d0f7ad434 |
child 189903 | 6e2c2a52ae8d14f682e4d3c55d327b03ee3e9d65 |
push id | 26999 |
push user | ryanvm@gmail.com |
push date | Mon, 23 Jun 2014 14:42:40 +0000 |
treeherder | mozilla-central@4a7f4ed3f08b [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | glandium |
bugs | 914563 |
milestone | 33.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/mach +++ b/mach @@ -53,9 +53,56 @@ def main(args): mach = load_mach(dir_path) sys.exit(mach.run(args[1:])) print('Could not run mach: No mach source directory found.') sys.exit(1) if __name__ == '__main__': + if sys.platform == 'win32': + # This is a complete hack to work around the fact that Windows + # multiprocessing needs to import the original module (ie: this + # file), but only works if it has a .py extension. + # + # We do this by a sort of two-level function interposing. The first + # level interposes forking.get_command_line() with our version defined + # in my_get_command_line(). Our version of get_command_line will + # replace the command string with the contents of the fork_interpose() + # function to be used in the subprocess. + # + # The subprocess then gets an interposed imp.find_module(), which we + # hack up to find 'mach' without the .py extension, since we already + # know where it is (it's us!). If we're not looking for 'mach', then + # the original find_module will suffice. + # + # See also: http://bugs.python.org/issue19946 + # And: https://bugzilla.mozilla.org/show_bug.cgi?id=914563 + import inspect + from multiprocessing import forking + global orig_command_line + + def fork_interpose(): + import imp + import os + orig_find_module = imp.find_module + def my_find_module(name, dirs): + if name == 'mach': + path = os.path.join(dirs[0], 'mach') + f = open(path) + return (f, path, ('', 'r', imp.PY_SOURCE)) + return orig_find_module(name, dirs) + + imp.find_module = my_find_module + from multiprocessing.forking import main; main() + + def my_get_command_line(): + fork_code, lineno = inspect.getsourcelines(fork_interpose) + # Remove the first line (for 'def fork_interpose():') and the three + # levels of indentation (12 spaces). + fork_string = ''.join(x[12:] for x in fork_code[1:]) + cmdline = orig_command_line() + cmdline[2] = fork_string + return cmdline + orig_command_line = forking.get_command_line + forking.get_command_line = my_get_command_line + main(sys.argv)