diff options
Diffstat (limited to 'backend/decky_loader/plugin')
| -rw-r--r-- | backend/decky_loader/plugin/plugin.py | 6 | ||||
| -rw-r--r-- | backend/decky_loader/plugin/sandboxed_plugin.py | 27 |
2 files changed, 24 insertions, 9 deletions
diff --git a/backend/decky_loader/plugin/plugin.py b/backend/decky_loader/plugin/plugin.py index f4b01ad3..a9a9ce29 100644 --- a/backend/decky_loader/plugin/plugin.py +++ b/backend/decky_loader/plugin/plugin.py @@ -109,7 +109,7 @@ class PluginWrapper: def start(self): if self.passive: return self - self.proc = Process(target=self.sandboxed_plugin.initialize, args=[self._socket], daemon=True) + self.proc = Process(target=self.sandboxed_plugin.initialize, args=[self._socket]) self.proc.start() self._listener_task = create_task(self._response_listener()) return self @@ -121,9 +121,11 @@ class PluginWrapper: if hasattr(self, "_socket"): await self._socket.write_single_line(dumps({ "stop": True, "uninstall": uninstall }, ensure_ascii=False)) await self._socket.close_socket_connection() + if self.proc: + self.proc.join() + await self.kill_if_still_running() if hasattr(self, "_listener_task"): self._listener_task.cancel() - await self.kill_if_still_running() async def kill_if_still_running(self): time = 0 diff --git a/backend/decky_loader/plugin/sandboxed_plugin.py b/backend/decky_loader/plugin/sandboxed_plugin.py index 07b04e7d..32330a9a 100644 --- a/backend/decky_loader/plugin/sandboxed_plugin.py +++ b/backend/decky_loader/plugin/sandboxed_plugin.py @@ -1,12 +1,12 @@ from os import path, environ -from signal import SIG_IGN, SIGINT, SIGTERM, signal +from signal import SIG_IGN, SIGINT, SIGTERM, getsignal, signal from importlib.util import module_from_spec, spec_from_file_location from json import dumps, loads from logging import getLogger from sys import exit, path as syspath, modules as sysmodules from traceback import format_exc from asyncio import (get_event_loop, new_event_loop, - set_event_loop, sleep) + set_event_loop) from setproctitle import setproctitle, setthreadtitle from .messages import SocketResponseDict, SocketMessageType @@ -19,6 +19,8 @@ from typing import List, TypeVar, Any DataType = TypeVar("DataType") +original_term_handler = getsignal(SIGTERM) + class SandboxedPlugin: def __init__(self, name: str, @@ -46,6 +48,8 @@ class SandboxedPlugin: self._socket = socket try: + # Ignore signals meant for parent Process + # TODO SURELY there's a better way to do this. signal(SIGINT, SIG_IGN) signal(SIGTERM, SIG_IGN) @@ -120,7 +124,14 @@ class SandboxedPlugin: except: self.log.error("Failed to start " + self.name + "!\n" + format_exc()) exit(0) - get_event_loop().run_forever() + try: + get_event_loop().run_forever() + except SystemExit: + pass + except: + self.log.error("Loop exited for " + self.name + "!\n" + format_exc()) + finally: + get_event_loop().close() async def _unload(self): try: @@ -156,6 +167,8 @@ class SandboxedPlugin: data = loads(message) if "stop" in data: + # Incase the loader needs to terminate our process soon + signal(SIGTERM, original_term_handler) self.log.info(f"Calling Loader unload function for {self.name}.") await self._unload() @@ -163,10 +176,10 @@ class SandboxedPlugin: self.log.info("Calling Loader uninstall function.") await self._uninstall() - get_event_loop().stop() - while get_event_loop().is_running(): - await sleep(0.1) - get_event_loop().close() + self.log.debug("Stopping event loop") + + loop = get_event_loop() + loop.call_soon_threadsafe(loop.stop) exit(0) d: SocketResponseDict = {"type": SocketMessageType.RESPONSE, "res": None, "success": True, "id": data["id"]} |
