diff --git a/SABnzbd.py b/SABnzbd.py index 5677011..e226386 100755 --- a/SABnzbd.py +++ b/SABnzbd.py @@ -1582,13 +1582,6 @@ def main(): else: cherrypy.engine._do_execv() - config.save_config() - - if sabnzbd.WINTRAY: - sabnzbd.WINTRAY.terminate = True - if sabnzbd.WIN32: - del_connection_info() - # Send our final goodbyes! notifier.send_notification("SABnzbd", T("SABnzbd shutdown finished"), "startup") logging.info("Leaving SABnzbd") diff --git a/sabnzbd/__init__.py b/sabnzbd/__init__.py index 669a3cf..d707297 100644 --- a/sabnzbd/__init__.py +++ b/sabnzbd/__init__.py @@ -362,7 +362,11 @@ def halt(): # Stop the windows tray icon if sabnzbd.WINTRAY: - sabnzbd.WINTRAY.terminate = True + sabnzbd.WINTRAY.stop() + + # Remove registry information + if sabnzbd.WIN32: + del_connection_info() sabnzbd.zconfig.remove_server() sabnzbd.utils.ssdp.stop_ssdp() @@ -393,7 +397,6 @@ def halt(): except: pass - # Stop Required Objects logging.debug("Stopping downloader") sabnzbd.Downloader.stop() try: @@ -438,31 +441,31 @@ def halt(): sabnzbd.__INITIALIZED__ = False +def notify_shutdown_loop(): + """ Trigger the main loop to wake up""" + with sabnzbd.SABSTOP_CONDITION: + sabnzbd.SABSTOP_CONDITION.notify() + + +def shutdown_program(): + """ Stop program after halting and saving """ + if not sabnzbd.SABSTOP: + logging.info("[%s] Performing SABnzbd shutdown", misc.caller_name()) + sabnzbd.halt() + cherrypy.engine.exit() + sabnzbd.SABSTOP = True + notify_shutdown_loop() + + def trigger_restart(timeout=None): """ Trigger a restart by setting a flag an shutting down CP """ # Sometimes we need to wait a bit to send good-bye to the browser if timeout: time.sleep(timeout) - if sabnzbd.WIN32: - # Remove connection info for faster restart - del_connection_info() - - # Leave the harder restarts to the polling in SABnzbd.py - if hasattr(sys, "frozen"): - sabnzbd.TRIGGER_RESTART = True - else: - # Add extra arguments - if sabnzbd.Downloader.paused: - sabnzbd.RESTART_ARGS.append("-p") - sys.argv = sabnzbd.RESTART_ARGS - - # Stop all services - sabnzbd.halt() - cherrypy.engine.exit() - - # Do the restart right now - cherrypy.engine._do_execv() + # Set the flag and wake up the main loop + sabnzbd.TRIGGER_RESTART = True + notify_shutdown_loop() ############################################################################## @@ -556,6 +559,7 @@ def add_url(url, pp=None, script=None, cat=None, priority=None, nzbname=None, pa def save_state(): """ Save all internal bookkeeping to disk """ + config.save_config() sabnzbd.ArticleCache.flush_articles() sabnzbd.NzbQueue.save() sabnzbd.BPSMeter.save() @@ -773,17 +777,6 @@ def system_standby(): powersup.linux_standby() -def shutdown_program(): - """ Stop program after halting and saving """ - if not sabnzbd.SABSTOP: - logging.info("[%s] Performing SABnzbd shutdown", misc.caller_name()) - sabnzbd.halt() - cherrypy.engine.exit() - sabnzbd.SABSTOP = True - with sabnzbd.SABSTOP_CONDITION: - sabnzbd.SABSTOP_CONDITION.notify() - - def restart_program(): """ Restart program (used by scheduler) """ logging.info("Scheduled restart request") diff --git a/sabnzbd/misc.py b/sabnzbd/misc.py index eab774d..bb0643f 100644 --- a/sabnzbd/misc.py +++ b/sabnzbd/misc.py @@ -64,6 +64,9 @@ if sabnzbd.WIN32: except ImportError: pass +if sabnzbd.DARWIN: + from PyObjCTools import AppHelper + def time_format(fmt): """ Return time-format string adjusted for 12/24 hour clock setting """ @@ -556,8 +559,6 @@ def exit_sab(value): sys.stderr.flush() sys.stdout.flush() if hasattr(sys, "frozen") and sabnzbd.DARWIN: - from PyObjCTools import AppHelper - AppHelper.stopEventLoop() sys.exit(value) diff --git a/sabnzbd/sabtray.py b/sabnzbd/sabtray.py index 9e6209a..94c1b36 100644 --- a/sabnzbd/sabtray.py +++ b/sabnzbd/sabtray.py @@ -21,6 +21,7 @@ sabtray.py - Systray icon for SABnzbd on Windows, contributed by Jan Schejbal import os import logging +from threading import Thread from time import sleep import sabnzbd @@ -188,7 +189,8 @@ class SABTrayThread(SysTrayIconThread): def shutdown(self, icon): self.hover_text = T("Shutdown") - sabnzbd.shutdown_program() + # In seperate thread, because the shutdown also stops the tray icon + Thread(target=sabnzbd.shutdown_program).start() def pause(self): sabnzbd.Scheduler.plan_resume(0) diff --git a/sabnzbd/utils/systrayiconthread.py b/sabnzbd/utils/systrayiconthread.py index fc6feb7..a01d997 100644 --- a/sabnzbd/utils/systrayiconthread.py +++ b/sabnzbd/utils/systrayiconthread.py @@ -21,12 +21,11 @@ from time import sleep class SysTrayIconThread(Thread): QUIT = "QUIT" SPECIAL_ACTIONS = [QUIT] - FIRST_ID = 1023 - terminate = False def __init__(self, icon, hover_text, menu_options, on_quit=None, default_menu_index=None, window_class_name=None): super().__init__() + self.terminate = False self.icon = icon self.icons = {} self.hover_text = hover_text @@ -80,12 +79,16 @@ class SysTrayIconThread(Thread): self.notify_id = None self.refresh_icon() + def stop(self): + self.terminate = True + sleep(0.15) + def run(self): self.initialize() while not self.terminate: win32gui.PumpWaitingMessages() self.doUpdates() - sleep(0.100) + sleep(0.1) win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, (self.hwnd, 0)) # Override this