Bug 914563 - Hack up mach to work with multiprocessing on Windows; r=glandium
--- 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)