summaryrefslogtreecommitdiff
path: root/backend/decky_loader/plugin/sandboxed_plugin.py
diff options
context:
space:
mode:
Diffstat (limited to 'backend/decky_loader/plugin/sandboxed_plugin.py')
-rw-r--r--backend/decky_loader/plugin/sandboxed_plugin.py33
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: