Exit "infinite" monitorloop when SyncRunner thread exits

The huge UI rework patch removed some obscure logic and special handling of
thread exit messages. It turns out that this was in fact still needed as a
specific exit message of the SyncRunner thread signified the threatmonitor
to quit.

We will want a nicer machinery for this in the future I guess, but fix the
eternal hang on exit by reintroducing a special exit message for the
SyncRunner thread, and return from the infinite monitor loop if SyncRunner
finishes.

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
This commit is contained in:
Sebastian Spaeth 2011-11-02 11:55:05 +01:00
parent 52ca66f055
commit 74d580bc68
2 changed files with 12 additions and 7 deletions

View File

@ -30,6 +30,8 @@ def syncaccount(threads, config, accountname):
threads.add(thread) threads.add(thread)
def syncitall(accounts, config): def syncitall(accounts, config):
# Special exit message for SyncRunner thread, so main thread can exit
currentThread().exit_message = 'SYNCRUNNER_EXITED_NORMALLY'
threads = threadlist() threads = threadlist()
for accountname in accounts: for accountname in accounts:
syncaccount(threads, config, accountname) syncaccount(threads, config, accountname)

View File

@ -95,19 +95,23 @@ def exitnotifymonitorloop(callback):
:type callback: a callable function :type callback: a callable function
""" """
global exitthreads global exitthreads
while 1: do_loop = True
while do_loop:
# Loop forever and call 'callback' for each thread that exited # Loop forever and call 'callback' for each thread that exited
try: try:
# we need a timeout in the get() call, so that ctrl-c can throw # we need a timeout in the get() call, so that ctrl-c can throw
# a SIGINT (http://bugs.python.org/issue1360). A timeout with empty # a SIGINT (http://bugs.python.org/issue1360). A timeout with empty
# Queue will raise `Empty`. # Queue will raise `Empty`.
thrd = exitthreads.get(True, 60) thrd = exitthreads.get(True, 60)
callback(thrd) # request to abort when callback returns true
do_loop = (callback(thrd) != True)
except Empty: except Empty:
pass pass
def threadexited(thread): def threadexited(thread):
"""Called when a thread exits.""" """Called when a thread exits.
Main thread is aborted when this returns True."""
ui = getglobalui() ui = getglobalui()
if thread.exit_exception: if thread.exit_exception:
if isinstance(thread.exit_exception, SystemExit): if isinstance(thread.exit_exception, SystemExit):
@ -117,12 +121,11 @@ def threadexited(thread):
raise SystemExit raise SystemExit
ui.threadException(thread) # Expected to terminate ui.threadException(thread) # Expected to terminate
sys.exit(100) # Just in case... sys.exit(100) # Just in case...
elif thread.exit_message == 'SYNC_WITH_TIMER_TERMINATE': elif thread.exit_message == 'SYNCRUNNER_EXITED_NORMALLY':
ui.terminate() return True
# Just in case...
sys.exit(100)
else: else:
ui.threadExited(thread) ui.threadExited(thread)
return False
class ExitNotifyThread(Thread): class ExitNotifyThread(Thread):
"""This class is designed to alert a "monitor" to the fact that a """This class is designed to alert a "monitor" to the fact that a