Implement true single-threading

Previously, we would spawn child threads for account synchronization
even if we had single-threading enabled. This prevented us from catching
the true location of exceptions, for example. Now, in single-threaded
mode, we perform the account synchronization truely in the main thread
which will ease our debugging.

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This commit is contained in:
Sebastian Spaeth 2011-01-12 11:15:12 +01:00 committed by Nicolas Sebrecht
parent 760698253b
commit b81b7d6001
2 changed files with 29 additions and 14 deletions

View File

@ -293,11 +293,8 @@ class OfflineImap:
remoterepos = None
localrepos = None
if options.singlethreading:
threadutil.initInstanceLimit("ACCOUNTLIMIT", 1)
else:
threadutil.initInstanceLimit("ACCOUNTLIMIT",
config.getdefaultint("general", "maxsyncaccounts", 1))
threadutil.initInstanceLimit("ACCOUNTLIMIT",
config.getdefaultint("general", "maxsyncaccounts", 1))
for reposname in config.getsectionlist('Repository'):
for instancename in ["FOLDER_" + reposname,
@ -326,15 +323,23 @@ class OfflineImap:
signal.signal(signal.SIGUSR1,sig_handler)
signal.signal(signal.SIGUSR2,sig_handler)
threadutil.initexitnotify()
t = threadutil.ExitNotifyThread(target=syncmaster.syncitall,
#various initializations that need to be performed:
threadutil.initexitnotify() #TODO: Why?
offlineimap.mbnames.init(config, syncaccounts)
if options.singlethreading:
#singlethreaded
self.sync_singlethreaded(syncaccounts, config, siglisteners)
else:
# multithreaded
t = threadutil.ExitNotifyThread(target=syncmaster.syncitall,
name='Sync Runner',
kwargs = {'accounts': syncaccounts,
'config': config,
'siglisteners': siglisteners})
t.setDaemon(1)
t.start()
threadutil.exitnotifymonitorloop(threadutil.threadexited)
t.setDaemon(1)
t.start()
threadutil.exitnotifymonitorloop(threadutil.threadexited)
except KeyboardInterrupt:
ui.terminate(1, errormsg = 'CTRL-C pressed, aborting...')
@ -344,4 +349,16 @@ class OfflineImap:
except:
ui.mainException()
def sync_singlethreaded(self, accs, config, siglisteners):
"""Executed if we do not want a separate syncmaster thread
:param accs: A list of accounts that should be synced
:param config: The CustomConfig object
:param siglisteners: The signal listeners list, defined in run()
"""
for accountname in accs:
account = offlineimap.accounts.SyncableAccount(config, accountname)
siglistener = offlineimap.accounts.SigListener()
siglisteners.append(siglistener)
threading.currentThread().name = "Account sync %s" % accountname
account.syncrunner(siglistener=siglistener)

View File

@ -16,7 +16,6 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
from offlineimap import mbnames
from offlineimap.threadutil import threadlist, InstanceLimitedThread, ExitNotifyThread
from offlineimap.accounts import SyncableAccount, SigListener
from threading import currentThread
@ -33,11 +32,10 @@ def syncaccount(threads, config, accountname, siglisteners):
thread.setDaemon(1)
thread.start()
threads.add(thread)
def syncitall(accounts, config, siglisteners):
currentThread().setExitMessage('SYNC_WITH_TIMER_TERMINATE')
threads = threadlist()
mbnames.init(config, accounts)
for accountname in accounts:
syncaccount(threads, config, accountname, siglisteners)
# Wait for the threads to finish.