From 8df2ac0a47bdfb09c752ff59530a07dd5bb74239 Mon Sep 17 00:00:00 2001 From: jgoerzen Date: Thu, 4 Jul 2002 01:02:10 +0100 Subject: [PATCH] /head: changeset 62 Initial work on threading support --- head/offlineimap.py | 24 +++++++++++++++--------- head/offlineimap/__init__.py | 2 +- head/offlineimap/imapserver.py | 10 +++------- head/offlineimap/threadutil.py | 29 +++++++++++++++++++++++++++++ head/offlineimap/ui/TTY.py | 5 +++-- head/offlineimap/ui/UIBase.py | 2 +- 6 files changed, 52 insertions(+), 20 deletions(-) create mode 100644 head/offlineimap/threadutil.py diff --git a/head/offlineimap.py b/head/offlineimap.py index 6b63b18..6440dea 100644 --- a/head/offlineimap.py +++ b/head/offlineimap.py @@ -17,9 +17,10 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -from offlineimap import imaplib, imaputil, imapserver, repository, folder, mbnames +from offlineimap import imaplib, imaputil, imapserver, repository, folder, mbnames, threadutil import re, os, os.path, offlineimap, sys from ConfigParser import ConfigParser +from threading import * # imaplib.Debug = 5 @@ -45,6 +46,17 @@ accounts = accounts.split(",") server = None remoterepos = None localrepos = None +passwords = {} +accountsemaphore = BoundedSemaphore(config.getint("general", "maxsyncaccounts")) + +# We have to gather passwords here -- don't want to have two threads +# asking for passwords simultaneously. + +for account in accounts: + if config.has_option(accountname, "remotepass"): + passwords[account] = config.get(accountname, "remotepass") + else: + passwords[account] = ui.getpass(accountname, config) def syncitall(): mailboxes = [] @@ -58,17 +70,11 @@ def syncitall(): port = None if config.has_option(accountname, "remoteport"): port = config.getint(accountname, "remoteport") - password = None - if config.has_option(accountname, "remotepass"): - password = config.get(accountname, "remotepass") - else: - password = ui.getpass(accountname, host, port, user) - # Save it for future reference. - config.set(accountname, "remotepass", password) ssl = config.getboolean(accountname, "ssl") # Connect to the remote server. - server = imapserver.IMAPServer(user, password, host, port, ssl) + server = imapserver.IMAPServer(user, passwords[accountname], + host, port, ssl) remoterepos = repository.IMAP.IMAPRepository(config, accountname, server) # Connect to the Maildirs. diff --git a/head/offlineimap/__init__.py b/head/offlineimap/__init__.py index 551f2de..18058c2 100644 --- a/head/offlineimap/__init__.py +++ b/head/offlineimap/__init__.py @@ -1,2 +1,2 @@ -import ui, folder, repository, mbnames +import ui, folder, repository, mbnames, threadutil diff --git a/head/offlineimap/imapserver.py b/head/offlineimap/imapserver.py index 2e530ed..3a89d03 100644 --- a/head/offlineimap/imapserver.py +++ b/head/offlineimap/imapserver.py @@ -16,7 +16,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -from offlineimap import imaplib, imaputil +from offlineimap import imaplib, imaputil, threadutil from threading import * class UsefulIMAPMixIn: @@ -129,21 +129,17 @@ class IMAPServer: to copy messages, then have them all wait for 3 available connections. It's OK if we have maxconnections + 1 or 2 threads, which is what this will help us do.""" - self.semaphore.acquire() - self.semaphore.release() + threadutil.semaphorewait(self.semaphore) def close(self): # Make sure I own all the semaphores. Let the threads finish # their stuff. This is a blocking method. self.connectionlock.acquire() - for i in range(self.maxconnections): - self.semaphore.acquire() + threadutil.semaphorereset(self.semaphore, self.maxconnections) for imapobj in self.assignedconnections + self.availableconnections: imapobj.logout() self.assignedconnections = [] self.availableconnections = [] - for i in range(self.maxconnections): - self.semaphore.release() self.connectionlock.release() diff --git a/head/offlineimap/threadutil.py b/head/offlineimap/threadutil.py new file mode 100644 index 0000000..9b047f4 --- /dev/null +++ b/head/offlineimap/threadutil.py @@ -0,0 +1,29 @@ +# Copyright (C) 2002 John Goerzen +# Thread support module +# +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +from Threading import * + +def semaphorewait(semaphore, originalstate): + """Wait until the semaphore gets back to its original state -- all acquired + resources released.""" + for i in range(originalstate): + semaphore.acquire() + # Now release these. + for i in range(originalstate): + semaphore.release() + diff --git a/head/offlineimap/ui/TTY.py b/head/offlineimap/ui/TTY.py index ce934d2..fd5d73f 100644 --- a/head/offlineimap/ui/TTY.py +++ b/head/offlineimap/ui/TTY.py @@ -9,9 +9,10 @@ class TTYUI(UIBase): def _msg(s, msg): print msg - def getpass(s, accountname, host, port, user): + def getpass(s, accountname, config): return getpass("%s: Enter password for %s on %s: " % - (accountname, user, host)) + (accountname, config.get(accountname, "remoteuser"), + config.get(accountname, "remotehost"))) def syncingmessages(s, sr, sf, dr, df): if s.verbose: diff --git a/head/offlineimap/ui/UIBase.py b/head/offlineimap/ui/UIBase.py index 76559ce..e9690a9 100644 --- a/head/offlineimap/ui/UIBase.py +++ b/head/offlineimap/ui/UIBase.py @@ -36,7 +36,7 @@ class UIBase: ################################################## INPUT - def getpass(s, accountname, host, port, user): + def getpass(s, accountname, config): raise NotImplementedException def folderlist(s, list):