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:
parent
52ca66f055
commit
74d580bc68
@ -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)
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user