Skip to content

Commit e3fe6fd

Browse files
committed
Ensure that program always exits
1 parent c4212e3 commit e3fe6fd

File tree

1 file changed

+28
-2
lines changed

1 file changed

+28
-2
lines changed

kasatk/__main__.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
import argparse
33
import asyncio
44
import logging
5+
import os
6+
import signal
7+
import subprocess
58
import sys
69
import threading
710
import tkinter
@@ -369,9 +372,32 @@ def main():
369372
root.geometry("500x400")
370373
root.iconbitmap("extra/icon.ico")
371374
scroll_frame = ScrollableFrame(root)
372-
KasaDevices(scroll_frame.scrollable_frame).pack()
375+
device_frame = KasaDevices(scroll_frame.scrollable_frame)
376+
device_frame.pack()
373377
scroll_frame.pack(fill=tkinter.BOTH, expand=True)
374-
root.mainloop()
378+
try:
379+
root.mainloop()
380+
except KeyboardInterrupt:
381+
logger.info("Caught KeyboardInterrupt. Shutting down.")
382+
finally:
383+
logger.info("Tkinter mainloop has exited.")
384+
# stop the event loop
385+
device_frame.event_loop.call_soon_threadsafe(device_frame.event_loop.stop)
386+
device_frame.event_loop.call_soon_threadsafe(device_frame.event_loop.close)
387+
388+
logger.info("Stopped asyncio event loop")
389+
# wait up to three seconds
390+
device_frame.event_thread.join(3)
391+
if device_frame.event_thread.is_alive():
392+
# If we get here, then it is likely that there is an uncooperative
393+
# asyncio task that is hogging the CPU and not surrending control
394+
# via await.
395+
logger.warning("Failed to stop event thread.")
396+
# Since asyncio is not behaving, we need to kill ourselves.
397+
if os.name == "nt":
398+
subprocess.run(["taskkill", "/IM", str(os.getpid()), "/F"])
399+
else:
400+
os.kill(os.getpid(), signal.SIGKILL)
375401

376402

377403
if __name__ == "__main__":

0 commit comments

Comments
 (0)