threading: add comments
Simplify the code. Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This commit is contained in:
parent
bf8bfbc872
commit
2611a0ba6a
@ -204,7 +204,10 @@ class SyncableAccount(Account):
|
|||||||
|
|
||||||
Derives from :class:`accounts.Account` but contains the additional
|
Derives from :class:`accounts.Account` but contains the additional
|
||||||
functions :meth:`syncrunner`, :meth:`sync`, :meth:`syncfolders`,
|
functions :meth:`syncrunner`, :meth:`sync`, :meth:`syncfolders`,
|
||||||
used for syncing."""
|
used for syncing.
|
||||||
|
|
||||||
|
In multi-threaded mode, one instance of this object is run per "account"
|
||||||
|
thread."""
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
Account.__init__(self, *args, **kwargs)
|
Account.__init__(self, *args, **kwargs)
|
||||||
@ -239,6 +242,8 @@ class SyncableAccount(Account):
|
|||||||
pass # Failed to delete for some reason.
|
pass # Failed to delete for some reason.
|
||||||
|
|
||||||
def syncrunner(self):
|
def syncrunner(self):
|
||||||
|
"""The target for both single and multi-threaded modes."""
|
||||||
|
|
||||||
self.ui.registerthread(self)
|
self.ui.registerthread(self)
|
||||||
try:
|
try:
|
||||||
accountmetadata = self.getaccountmeta()
|
accountmetadata = self.getaccountmeta()
|
||||||
|
@ -16,24 +16,29 @@
|
|||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
from offlineimap.threadutil import threadlist, InstanceLimitedThread
|
from offlineimap.threadutil import threadlist, InstanceLimitedThread, NORMAL_EXIT
|
||||||
from offlineimap.accounts import SyncableAccount
|
from offlineimap.accounts import SyncableAccount
|
||||||
from threading import currentThread
|
from threading import currentThread
|
||||||
|
|
||||||
def syncaccount(threads, config, accountname):
|
def syncaccount(config, accountname):
|
||||||
|
"""Return a new running thread for this account."""
|
||||||
|
|
||||||
account = SyncableAccount(config, accountname)
|
account = SyncableAccount(config, accountname)
|
||||||
thread = InstanceLimitedThread(instancename = 'ACCOUNTLIMIT',
|
thread = InstanceLimitedThread(instancename = 'ACCOUNTLIMIT',
|
||||||
target = account.syncrunner,
|
target = account.syncrunner,
|
||||||
name = "Account sync %s" % accountname)
|
name = "Account sync %s" % accountname)
|
||||||
thread.setDaemon(True)
|
thread.setDaemon(True)
|
||||||
thread.start()
|
thread.start()
|
||||||
threads.add(thread)
|
return thread
|
||||||
|
|
||||||
def syncitall(accounts, config):
|
def syncitall(accounts, config):
|
||||||
# Special exit message for SyncRunner thread, so main thread can exit
|
"""The target when in multithreading mode."""
|
||||||
currentThread().exit_message = 'SYNCRUNNER_EXITED_NORMALLY'
|
|
||||||
threads = threadlist()
|
# Special exit message for SyncRunner thread, so main thread can exit.
|
||||||
|
currentThread().exit_message = NORMAL_EXIT
|
||||||
|
threads = threadlist() # The collection of threads.
|
||||||
for accountname in accounts:
|
for accountname in accounts:
|
||||||
syncaccount(threads, config, accountname)
|
# Start a new thread per account and store it in the collection.
|
||||||
|
threads.add(syncaccount(config, accountname))
|
||||||
# Wait for the threads to finish.
|
# Wait for the threads to finish.
|
||||||
threads.reset()
|
threads.wait() # Blocks until all accounts are processed.
|
||||||
|
@ -25,6 +25,9 @@ import os.path
|
|||||||
import sys
|
import sys
|
||||||
from offlineimap.ui import getglobalui
|
from offlineimap.ui import getglobalui
|
||||||
|
|
||||||
|
|
||||||
|
NORMAL_EXIT = 'SYNCRUNNER_EXITED_NORMALLY'
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# General utilities
|
# General utilities
|
||||||
######################################################################
|
######################################################################
|
||||||
@ -70,7 +73,7 @@ class threadlist:
|
|||||||
finally:
|
finally:
|
||||||
self.lock.release()
|
self.lock.release()
|
||||||
|
|
||||||
def reset(self):
|
def wait(self):
|
||||||
while 1:
|
while 1:
|
||||||
thread = self.pop()
|
thread = self.pop()
|
||||||
if not thread:
|
if not thread:
|
||||||
@ -129,7 +132,7 @@ 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 == 'SYNCRUNNER_EXITED_NORMALLY':
|
elif thread.exit_message == NORMAL_EXIT:
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
ui.threadExited(thread)
|
ui.threadExited(thread)
|
||||||
@ -157,6 +160,8 @@ class ExitNotifyThread(Thread):
|
|||||||
self._exit_stacktrace = None
|
self._exit_stacktrace = None
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
"""Allow profiling of a run."""
|
||||||
|
|
||||||
global exitthreads
|
global exitthreads
|
||||||
try:
|
try:
|
||||||
if not ExitNotifyThread.profiledir: # normal case
|
if not ExitNotifyThread.profiledir: # normal case
|
||||||
|
Loading…
Reference in New Issue
Block a user