Skip to content

Commit

Permalink
Linux: add freeze_support, Launcher: use spawn (ArchipelagoMW#1890)
Browse files Browse the repository at this point in the history
  • Loading branch information
black-sliver authored Jun 25, 2023
1 parent f3e2e42 commit a96ff8d
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 1 deletion.
3 changes: 2 additions & 1 deletion Launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,8 @@ def main(args: Optional[Union[argparse.Namespace, dict]] = None):

if __name__ == '__main__':
init_logging('Launcher')
multiprocessing.freeze_support()
Utils.freeze_support()
multiprocessing.set_start_method("spawn") # if launched process uses kivy, fork won't work
parser = argparse.ArgumentParser(description='Archipelago Launcher')
parser.add_argument('Patch|Game|Component', type=str, nargs='?',
help="Pass either a patch file, a generated game or the name of a component to run.")
Expand Down
47 changes: 47 additions & 0 deletions Utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -792,3 +792,50 @@ def deprecate(message: str):
raise Exception(message)
import warnings
warnings.warn(message)

def _extend_freeze_support() -> None:
"""Extend multiprocessing.freeze_support() to also work on Non-Windows for spawn."""
# upstream issue: https://github.com/python/cpython/issues/76327
# code based on https://github.com/pyinstaller/pyinstaller/blob/develop/PyInstaller/hooks/rthooks/pyi_rth_multiprocessing.py#L26
import multiprocessing
import multiprocessing.spawn

def _freeze_support() -> None:
"""Minimal freeze_support. Only apply this if frozen."""
from subprocess import _args_from_interpreter_flags

# Prevent `spawn` from trying to read `__main__` in from the main script
multiprocessing.process.ORIGINAL_DIR = None

# Handle the first process that MP will create
if (
len(sys.argv) >= 2 and sys.argv[-2] == '-c' and sys.argv[-1].startswith((
'from multiprocessing.semaphore_tracker import main', # Py<3.8
'from multiprocessing.resource_tracker import main', # Py>=3.8
'from multiprocessing.forkserver import main'
)) and set(sys.argv[1:-2]) == set(_args_from_interpreter_flags())
):
exec(sys.argv[-1])
sys.exit()

# Handle the second process that MP will create
if multiprocessing.spawn.is_forking(sys.argv):
kwargs = {}
for arg in sys.argv[2:]:
name, value = arg.split('=')
if value == 'None':
kwargs[name] = None
else:
kwargs[name] = int(value)
multiprocessing.spawn.spawn_main(**kwargs)
sys.exit()

if not is_windows and is_frozen():
multiprocessing.freeze_support = multiprocessing.spawn.freeze_support = _freeze_support


def freeze_support() -> None:
"""This behaves like multiprocessing.freeze_support but also works on Non-Windows."""
import multiprocessing
_extend_freeze_support()
multiprocessing.freeze_support()

0 comments on commit a96ff8d

Please sign in to comment.