UIBase: Fix and cleanup register/unregisterthread

Registering a thread (associating it with a certain account name) would
fail if it was already registered. However, as we a) never unregister most
threads (bad) and b) single-threaded mode reuses threads, we failed when
syncing multiple accounts in single-threading mode.

This commit cleans up the functions to not make re-registering a thread
fatal (it could be legitimate, however it *should* not occur). Future
work needs to be done to unregister new threads at the appropriate places.

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
This commit is contained in:
Sebastian Spaeth 2011-09-29 15:43:01 +02:00
parent b50668434e
commit 8970a1500b
2 changed files with 27 additions and 19 deletions

View File

@ -18,3 +18,7 @@ Changes
Bug Fixes Bug Fixes
--------- ---------
* Syncing multiple accounts in single-threaded mode would fail as we try
to "register" a thread as belonging to two accounts which was
fatal. Make it non-fatal (it can be legitimate).

View File

@ -47,6 +47,7 @@ class UIBase:
s.debugmessages = {} s.debugmessages = {}
s.debugmsglen = 50 s.debugmsglen = 50
s.threadaccounts = {} s.threadaccounts = {}
"""dict linking active threads (k) to account names (v)"""
s.logfile = None s.logfile = None
s.exc_queue = Queue() s.exc_queue = Queue()
"""saves all occuring exceptions, so we can output them at the end""" """saves all occuring exceptions, so we can output them at the end"""
@ -117,29 +118,32 @@ class UIBase:
if exc_traceback: if exc_traceback:
self._msg(traceback.format_tb(exc_traceback)) self._msg(traceback.format_tb(exc_traceback))
def registerthread(s, account): def registerthread(self, account):
"""Provides a hint to UIs about which account this particular """Register current thread as being associated with an account name"""
thread is processing.""" cur_thread = threading.currentThread()
if s.threadaccounts.has_key(threading.currentThread()): if cur_thread in self.threadaccounts:
raise ValueError, "Thread %s already registered (old %s, new %s)" %\ # was already associated with an old account, update info
(threading.currentThread().getName(), self.debug('thread', "Register thread '%s' (previously '%s', now "
s.getthreadaccount(s), account) "'%s')" % (cur_thread.getName(),
s.threadaccounts[threading.currentThread()] = account self.getthreadaccount(cur_thread), account))
s.debug('thread', "Register new thread '%s' (account '%s')" %\ else:
(threading.currentThread().getName(), account)) self.debug('thread', "Register new thread '%s' (account '%s')" %\
(cur_thread.getName(), account))
self.threadaccounts[cur_thread] = account
def unregisterthread(s, thr): def unregisterthread(self, thr):
"""Recognizes a thread has exited.""" """Unregister a thread as being associated with an account name"""
if s.threadaccounts.has_key(thr): if self.threadaccounts.has_key(thr):
del s.threadaccounts[thr] del self.threadaccounts[thr]
s.debug('thread', "Unregister thread '%s'" % thr.getName()) self.debug('thread', "Unregister thread '%s'" % thr.getName())
def getthreadaccount(s, thr = None): def getthreadaccount(self, thr = None):
"""Get name of account for a thread (current if None)"""
if not thr: if not thr:
thr = threading.currentThread() thr = threading.currentThread()
if s.threadaccounts.has_key(thr): if thr in self.threadaccounts:
return s.threadaccounts[thr] return self.threadaccounts[thr]
return '*Control' return '*Control' # unregistered thread is '*Control'
def debug(s, debugtype, msg): def debug(s, debugtype, msg):
thisthread = threading.currentThread() thisthread = threading.currentThread()