diff options
Diffstat (limited to 'backend/decky_loader/plugin/sandboxed_plugin.py')
| -rw-r--r-- | backend/decky_loader/plugin/sandboxed_plugin.py | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/backend/decky_loader/plugin/sandboxed_plugin.py b/backend/decky_loader/plugin/sandboxed_plugin.py index 23575900..b730fa98 100644 --- a/backend/decky_loader/plugin/sandboxed_plugin.py +++ b/backend/decky_loader/plugin/sandboxed_plugin.py @@ -4,8 +4,9 @@ from importlib.util import module_from_spec, spec_from_file_location from json import dumps, loads from logging import getLogger from traceback import format_exc -from asyncio import (get_event_loop, new_event_loop, +from asyncio import (ensure_future, get_event_loop, new_event_loop, set_event_loop) +from signal import SIGINT, SIGTERM from setproctitle import setproctitle, setthreadtitle from .messages import SocketResponseDict, SocketMessageType @@ -38,6 +39,7 @@ class SandboxedPlugin: self.version = version self.author = author self.api_version = api_version + self.shutdown_running = False self.log = getLogger("sandboxed_plugin") @@ -48,7 +50,11 @@ class SandboxedPlugin: setproctitle(f"{self.name} ({self.file})") setthreadtitle(self.name) - set_event_loop(new_event_loop()) + loop = new_event_loop() + set_event_loop(loop) + # When running Decky manually in a terminal, ctrl-c will trigger this, so we have to handle it properly + loop.add_signal_handler(SIGINT, lambda: ensure_future(self.shutdown())) + loop.add_signal_handler(SIGTERM, lambda: ensure_future(self.shutdown())) if self.passive: return setgid(UserType.ROOT if "root" in self.flags else UserType.HOST_USER) @@ -155,22 +161,27 @@ class SandboxedPlugin: self.log.error("Failed to uninstall " + self.name + "!\n" + format_exc()) pass - async def on_new_message(self, message : str) -> str|None: - data = loads(message) - - if "stop" in data: + async def shutdown(self, uninstall: bool = False): + if not self.shutdown_running: + self.shutdown_running = True self.log.info(f"Calling Loader unload function for {self.name}.") await self._unload() - if data.get('uninstall'): + if uninstall: self.log.info("Calling Loader uninstall function.") await self._uninstall() - self.log.debug("Stopping event loop") + self.log.debug("Stopping event loop") - loop = get_event_loop() - loop.call_soon_threadsafe(loop.stop) - sys.exit(0) + loop = get_event_loop() + loop.call_soon_threadsafe(loop.stop) + sys.exit(0) + + async def on_new_message(self, message : str) -> str|None: + data = loads(message) + + if "stop" in data: + await self.shutdown(data.get('uninstall')) d: SocketResponseDict = {"type": SocketMessageType.RESPONSE, "res": None, "success": True, "id": data["id"]} try: |
