threading: improve variable names and factorize code

Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This commit is contained in:
Nicolas Sebrecht 2016-05-18 02:42:09 +02:00
parent 0addcbabf0
commit e0fdcb3852
5 changed files with 29 additions and 24 deletions

View File

@ -29,6 +29,8 @@ from offlineimap.threadutil import InstanceLimitedThread
import six
FOLDER_NAMESPACE = 'LIMITED_FOLDER_'
try:
import fcntl
except:
@ -354,9 +356,11 @@ class SyncableAccount(Account):
continue # Ignore filtered folder
if not globals.options.singlethreading:
thread = InstanceLimitedThread(
instancename = 'FOLDER_' + self.remoterepos.getname(),
limitNamespace = "%s%s"% (
FOLDER_NAMESPACE, self.remoterepos.getname()),
target = syncfolder,
name = "Folder %s [acc: %s]"% (remotefolder.getexplainedname(), self),
name = "Folder %s [acc: %s]"% (
remotefolder.getexplainedname(), self),
args = (self, remotefolder, quick)
)
thread.start()

View File

@ -134,7 +134,7 @@ class BaseFolder(object):
return True
def getcopyinstancelimit(self):
def getinstancelimitnamespace(self):
"""For threading folders, returns the instancelimitname for
InstanceLimitedThreads."""
@ -872,7 +872,7 @@ class BaseFolder(object):
if self.suggeststhreads() and not globals.options.singlethreading:
self.waitforthread()
thread = threadutil.InstanceLimitedThread(
self.getcopyinstancelimit(),
self.getinstancelimitnamespace(),
target = self.copymessageto,
name = "Copy message from %s:%s" % (self.repository, self),
args = (uid, dstfolder, statusfolder)

View File

@ -32,6 +32,7 @@ import six
# Globals
CRLF = '\r\n'
MSGCOPY_NAMESPACE = 'MSGCOPY_'
# NB: message returned from getmessage() will have '\n' all over the place,
@ -88,8 +89,8 @@ class IMAPFolder(BaseFolder):
OfflineImapError.ERROR.REPO), None, exc_info()[2])
# Interface from BaseFolder
def getcopyinstancelimit(self):
return 'MSGCOPY_' + self.repository.getname()
def getinstancelimitnamespace(self):
return MSGCOPY_NAMESPACE + self.repository.getname()
# Interface from BaseFolder
def get_uidvalidity(self):

View File

@ -31,6 +31,7 @@ from offlineimap.ui import UI_LIST, setglobalui, getglobalui
from offlineimap.CustomConfig import CustomConfigParser
from offlineimap.utils import stacktrace
from offlineimap.repository import Repository
from offlineimap.folder.IMAP import MSGCOPY_NAMESPACE
import traceback
import collections
@ -45,7 +46,7 @@ def syncitall(list_accounts, config):
# Start a new thread per account and store it in the collection.
account = accounts.SyncableAccount(config, accountname)
thread = threadutil.InstanceLimitedThread(
instancename = ACCOUNT_LIMITED_THREAD_NAME,
ACCOUNT_LIMITED_THREAD_NAME,
target = account.syncrunner,
name = "Account sync %s"% accountname
)
@ -298,8 +299,8 @@ class OfflineImap:
# connections for a remote IMAP server, why do we allow twice this
# number? The max connections number is used by both the FOLDER_ and
# the MSGCOPY_ prefixes!
for instancename in ["FOLDER_" + reposname,
"MSGCOPY_" + reposname]:
for instancename in [accounts.FOLDER_NAMESPACE + reposname,
MSGCOPY_NAMESPACE + reposname]:
if options.singlethreading:
threadutil.initInstanceLimit(instancename, 1)
else:

View File

@ -221,37 +221,36 @@ class ExitNotifyThread(Thread):
# Instance-limited threads
######################################################################
instancelimitedsems = {}
limitedNamespaces = {}
def initInstanceLimit(instancename, instancemax):
def initInstanceLimit(limitNamespace, instancemax):
"""Initialize the instance-limited thread implementation.
Run up to intancemax threads for the given instancename. This allows
to honor maxsyncaccounts and maxconnections."""
Run up to intancemax threads for the given limitNamespace. This allows to
honor maxsyncaccounts and maxconnections."""
global instancelimitedsems
global limitedNamespaces
if not instancename in instancelimitedsems:
instancelimitedsems[instancename] = BoundedSemaphore(instancemax)
if not limitNamespace in limitedNamespaces:
limitedNamespaces[limitNamespace] = BoundedSemaphore(instancemax)
class InstanceLimitedThread(ExitNotifyThread):
def __init__(self, instancename, *args, **kwargs):
# XXX: this is not a instance name, is it?
self.instancename = instancename
def __init__(self, limitNamespace, *args, **kwargs):
self.limitNamespace = limitNamespace
super(InstanceLimitedThread, self).__init__(*args, **kwargs)
def start(self):
global instancelimitedsems
global limitedNamespaces
instancelimitedsems[self.instancename].acquire()
limitedNamespaces[self.limitNamespace].acquire()
ExitNotifyThread.start(self)
def run(self):
global instancelimitedsems
global limitedNamespaces
try:
ExitNotifyThread.run(self)
finally:
if instancelimitedsems and instancelimitedsems[self.instancename]:
instancelimitedsems[self.instancename].release()
if limitedNamespaces and limitedNamespaces[self.limitNamespace]:
limitedNamespaces[self.limitNamespace].release()