Merge branch 'ss/remove-multilock' into next
This commit is contained in:
commit
0b5d15350d
@ -246,54 +246,3 @@ class InstanceLimitedThread(ExitNotifyThread):
|
|||||||
finally:
|
finally:
|
||||||
if instancelimitedsems and instancelimitedsems[self.instancename]:
|
if instancelimitedsems and instancelimitedsems[self.instancename]:
|
||||||
instancelimitedsems[self.instancename].release()
|
instancelimitedsems[self.instancename].release()
|
||||||
|
|
||||||
|
|
||||||
######################################################################
|
|
||||||
# Multi-lock -- capable of handling a single thread requesting a lock
|
|
||||||
# multiple times
|
|
||||||
######################################################################
|
|
||||||
|
|
||||||
class MultiLock:
|
|
||||||
def __init__(self):
|
|
||||||
self.lock = Lock()
|
|
||||||
self.statuslock = Lock()
|
|
||||||
self.locksheld = {}
|
|
||||||
|
|
||||||
def acquire(self):
|
|
||||||
"""Obtain a lock. Provides nice support for a single
|
|
||||||
thread trying to lock it several times -- as may be the case
|
|
||||||
if one I/O-using object calls others, while wanting to make it all
|
|
||||||
an atomic operation. Keeps a "lock request count" for the current
|
|
||||||
thread, and acquires the lock when it goes above zero, releases when
|
|
||||||
it goes below one.
|
|
||||||
|
|
||||||
This call is always blocking."""
|
|
||||||
|
|
||||||
# First, check to see if this thread already has a lock.
|
|
||||||
# If so, increment the lock count and just return.
|
|
||||||
self.statuslock.acquire()
|
|
||||||
try:
|
|
||||||
threadid = thread.get_ident()
|
|
||||||
|
|
||||||
if threadid in self.locksheld:
|
|
||||||
self.locksheld[threadid] += 1
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
# This is safe because it is a per-thread structure
|
|
||||||
self.locksheld[threadid] = 1
|
|
||||||
finally:
|
|
||||||
self.statuslock.release()
|
|
||||||
self.lock.acquire()
|
|
||||||
|
|
||||||
def release(self):
|
|
||||||
self.statuslock.acquire()
|
|
||||||
try:
|
|
||||||
threadid = thread.get_ident()
|
|
||||||
if self.locksheld[threadid] > 1:
|
|
||||||
self.locksheld[threadid] -= 1
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
del self.locksheld[threadid]
|
|
||||||
self.lock.release()
|
|
||||||
finally:
|
|
||||||
self.statuslock.release()
|
|
||||||
|
@ -16,10 +16,9 @@
|
|||||||
# 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 threading import *
|
from threading import RLock, currentThread
|
||||||
from offlineimap.ui.UIBase import UIBase
|
from offlineimap.ui.UIBase import UIBase
|
||||||
import thread
|
import thread
|
||||||
from offlineimap.threadutil import MultiLock
|
|
||||||
|
|
||||||
class BlinkenBase:
|
class BlinkenBase:
|
||||||
"""This is a mix-in class that should be mixed in with either UIBase
|
"""This is a mix-in class that should be mixed in with either UIBase
|
||||||
@ -85,7 +84,8 @@ class BlinkenBase:
|
|||||||
def init_banner(s):
|
def init_banner(s):
|
||||||
s.availablethreadframes = {}
|
s.availablethreadframes = {}
|
||||||
s.threadframes = {}
|
s.threadframes = {}
|
||||||
s.tflock = MultiLock()
|
#tflock protects the s.threadframes manipulation to only happen from 1 thread
|
||||||
|
s.tflock = RLock()
|
||||||
|
|
||||||
def threadExited(s, thread):
|
def threadExited(s, thread):
|
||||||
threadid = thread.threadid
|
threadid = thread.threadid
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
# 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 threading import Lock, Event
|
from threading import RLock, Lock, Event
|
||||||
import time
|
import time
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
@ -32,7 +32,8 @@ acctkeys = '1234567890abcdefghijklmnoprstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-=;/.,'
|
|||||||
class CursesUtil:
|
class CursesUtil:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.pairlock = Lock()
|
self.pairlock = Lock()
|
||||||
self.iolock = offlineimap.threadutil.MultiLock()
|
# iolock protects access to the
|
||||||
|
self.iolock = RLock()
|
||||||
self.start()
|
self.start()
|
||||||
|
|
||||||
def initpairs(self):
|
def initpairs(self):
|
||||||
@ -45,9 +46,20 @@ class CursesUtil:
|
|||||||
self.pairlock.release()
|
self.pairlock.release()
|
||||||
|
|
||||||
def lock(self):
|
def lock(self):
|
||||||
|
"""Locks the Curses ui thread
|
||||||
|
|
||||||
|
Can be invoked multiple times from the owning thread. Invoking
|
||||||
|
from a non-owning thread blocks and waits until it has been
|
||||||
|
unlocked by the owning thread."""
|
||||||
self.iolock.acquire()
|
self.iolock.acquire()
|
||||||
|
|
||||||
def unlock(self):
|
def unlock(self):
|
||||||
|
"""Unlocks the Curses ui thread
|
||||||
|
|
||||||
|
Decrease the lock counter by one and unlock the ui thread if the
|
||||||
|
counter reaches 0. Only call this method when the calling
|
||||||
|
thread owns the lock. A RuntimeError is raised if this method is
|
||||||
|
called when the lock is unlocked."""
|
||||||
self.iolock.release()
|
self.iolock.release()
|
||||||
|
|
||||||
def locked(self, target, *args, **kwargs):
|
def locked(self, target, *args, **kwargs):
|
||||||
|
@ -15,10 +15,10 @@
|
|||||||
# 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
|
||||||
|
|
||||||
import offlineimap.version
|
|
||||||
import urllib, sys, re, time, traceback, threading, thread
|
import urllib, sys, re, time, traceback, threading, thread
|
||||||
from UIBase import UIBase
|
from UIBase import UIBase
|
||||||
from threading import *
|
from threading import *
|
||||||
|
import offlineimap
|
||||||
|
|
||||||
protocol = '6.0.0'
|
protocol = '6.0.0'
|
||||||
|
|
||||||
@ -173,7 +173,7 @@ class MachineUI(UIBase):
|
|||||||
s.outputlock.release()
|
s.outputlock.release()
|
||||||
|
|
||||||
def init_banner(s):
|
def init_banner(s):
|
||||||
s._printData('initbanner', offlineimap.version.banner)
|
s._printData('initbanner', offlineimap.banner)
|
||||||
|
|
||||||
def callhook(s, msg):
|
def callhook(s, msg):
|
||||||
s._printData('callhook', msg)
|
s._printData('callhook', msg)
|
||||||
|
@ -16,10 +16,10 @@
|
|||||||
# 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
|
||||||
|
|
||||||
import offlineimap.version
|
|
||||||
import re, time, sys, traceback, threading, thread
|
import re, time, sys, traceback, threading, thread
|
||||||
from StringIO import StringIO
|
from StringIO import StringIO
|
||||||
from Queue import Empty
|
from Queue import Empty
|
||||||
|
import offlineimap
|
||||||
|
|
||||||
debugtypes = {'imap': 'IMAP protocol debugging',
|
debugtypes = {'imap': 'IMAP protocol debugging',
|
||||||
'maildir': 'Maildir repository debugging',
|
'maildir': 'Maildir repository debugging',
|
||||||
|
Loading…
Reference in New Issue
Block a user