From: W. Trevor King Date: Fri, 13 Aug 2010 11:31:19 +0000 (-0400) Subject: Removed hooke.compat.forking since issue8534 can't be monkey patched. X-Git-Url: http://git.tremily.us/?p=hooke.git;a=commitdiff_plain;h=40a2a345c07bf63336829a52fdbdcfb7a8bd99a5 Removed hooke.compat.forking since issue8534 can't be monkey patched. You'll have to apply simonsteiner's issue8534 patch http://bugs.python.org/file17092/forking.patch to your Python's multiprocessing.forking by hand (on MS Windows). See http://bugs.python.org/issue8534 http://docs.python.org/library/multiprocessing.html#windows Here's what happens on Linux: 1) main program starts running 2) monkey patch applied 3) multiprocessing.Process() forks off the subprocess. a) child process inherits parent's memory, getting all currently imported libraries for free. b) child process continues successful run. 4) main process continues successful run. Here's what happens on MS Windows: 1) main program starts running 2) monkey patch applied 3) multiprocessing.Process() spawns subprocess, feeding its pickling state to the child through the connecting socket. a) child process starts, loading (unpatched) base Python libraries to figure out what it should do. b) child process starts reading pickled parent state. c) child process attempts to find hooke to unpickle parent state. d) child process cannot find hooke (with unpatched multiprocessing) and dies. 4) main process dies from lack of child. After applying simonsteiner's issue8534 patch, Windows looks like: 1) main program starts running 2) multiprocessing.Process() spawns subprocess, feeding its pickling state to the child through the connecting socket. a) child process starts, loading (patched) base Python libraries to figure out what it should do. b) child process starts reading pickled parent state. c) child process attempts to find hooke to unpickle parent state. d) child process loads hooke. e) child process continues successful run. 3) main process continues successful run. --- diff --git a/hooke/compat/forking.py b/hooke/compat/forking.py deleted file mode 100644 index 5a161a9..0000000 --- a/hooke/compat/forking.py +++ /dev/null @@ -1,113 +0,0 @@ -# Copyright (C) 2010 W. Trevor King -# -# This file is part of Hooke. -# -# Hooke is free software: you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# Hooke is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General -# Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with Hooke. If not, see -# . - -"""Dynamically patch :func:`multiprocessing.forking.prepare`. - -`prepare` can have trouble `loading modules from .eggs`_ or -`finding hooke on Windows`_. Importing this module applies the -suggested patch dynamically. - -.. _loading modules from .eggs: http://bugs.python.org/issue8534 -.. _finding hooke on Windows: - http://code.google.com/p/hooke/issues/detail?id=40#c17 -""" - -import logging -import multiprocessing.forking - - -def prepare(data): - ''' - Try to get current process ready to unpickle process object - ''' - old_main_modules.append(sys.modules['__main__']) - - if 'name' in data: - process.current_process().name = data['name'] - - if 'authkey' in data: - process.current_process()._authkey = data['authkey'] - - if 'log_to_stderr' in data and data['log_to_stderr']: - util.log_to_stderr() - - if 'log_level' in data: - util.get_logger().setLevel(data['log_level']) - - if 'sys_path' in data: - sys.path = data['sys_path'] - - if 'sys_argv' in data: - sys.argv = data['sys_argv'] - - if 'dir' in data: - os.chdir(data['dir']) - - if 'orig_dir' in data: - process.ORIGINAL_DIR = data['orig_dir'] - - if 'main_path' in data: - main_path = data['main_path'] - main_name = os.path.splitext(os.path.basename(main_path))[0] - if main_name == '__init__': - main_name = os.path.basename(os.path.dirname(main_path)) - - if main_name != 'ipython': - import imp - - if main_path is None: - dirs = None - elif os.path.basename(main_path).startswith('__init__.py'): - dirs = [os.path.dirname(os.path.dirname(main_path))] - else: - dirs = [os.path.dirname(main_path)] - - assert main_name not in sys.modules, main_name - - try: - main_module = __import__(main_name) - except ImportError: - file, path_name, etc = imp.find_module(main_name, dirs) - - try: - # We would like to do "imp.load_module('__main__', ...)" - # here. However, that would cause 'if __name__ == - # "__main__"' clauses to be executed. - main_module = imp.load_module( - '__parents_main__', file, path_name, etc - ) - finally: - if file: - file.close() - - sys.modules['__main__'] = main_module - main_module.__name__ = '__main__' - - # Try to make the potentially picklable objects in - # sys.modules['__main__'] realize they are in the main - # module -- somewhat ugly. - for obj in main_module.__dict__.values(): - try: - if obj.__module__ == '__parents_main__': - obj.__module__ = '__main__' - except Exception: - pass -multiprocessing.forking.prepare = prepare - -logging.warn( - 'Monkey patched multiprocessing.forking.prepare for issue8534') diff --git a/hooke/hooke.py b/hooke/hooke.py index c475d3a..b69bdf8 100644 --- a/hooke/hooke.py +++ b/hooke/hooke.py @@ -71,7 +71,6 @@ from . import playlist from . import plugin as plugin_mod from . import driver as driver_mod from . import ui -from .compat import forking as forking # dynamically patch multiprocessing.forking class Hooke (object):