]> code.delx.au - offlineimap/blobdiff - offlineimap/threadutil.py
Merge branch 'master' of ssh://jpgarch@complete.org/~jpgarch/git/offlineimap
[offlineimap] / offlineimap / threadutil.py
index 665d33413cb754c7b0dde100138c615b3d14424e..b516f68671b95be9e850794e2207a00822c686a9 100644 (file)
@@ -18,7 +18,8 @@
 
 from threading import *
 from StringIO import StringIO
 
 from threading import *
 from StringIO import StringIO
-import sys, traceback, thread
+from Queue import Queue, Empty
+import sys, traceback, thread, time
 from offlineimap.ui import UIBase       # for getglobalui()
 
 profiledir = None
 from offlineimap.ui import UIBase       # for getglobalui()
 
 profiledir = None
@@ -88,8 +89,7 @@ class threadlist:
 # Exit-notify threads
 ######################################################################
 
 # Exit-notify threads
 ######################################################################
 
-exitcondition = Condition(Lock())
-exitthreads = []
+exitthreads = Queue(100)
 inited = 0
 
 def initexitnotify():
 inited = 0
 
 def initexitnotify():
@@ -110,17 +110,13 @@ def exitnotifymonitorloop(callback):
     an ExitNotifyThread, or else an infinite loop may result.  Furthermore,
     the monitor will hold the lock all the while the other thread is waiting.
     """
     an ExitNotifyThread, or else an infinite loop may result.  Furthermore,
     the monitor will hold the lock all the while the other thread is waiting.
     """
-    global exitcondition, exitthreads
+    global exitthreads
     while 1:                            # Loop forever.
     while 1:                            # Loop forever.
-        exitcondition.acquire()
         try:
         try:
-            while not len(exitthreads):
-                exitcondition.wait(1)
-
-            while len(exitthreads):
-                callback(exitthreads.pop(0)) # Pull off in order added!
-        finally:
-            exitcondition.release()
+            thrd = exitthreads.get(False)
+            callback(thrd)
+        except Empty:
+            time.sleep(1)
 
 def threadexited(thread):
     """Called when a thread exits."""
 
 def threadexited(thread):
     """Called when a thread exits."""
@@ -146,7 +142,7 @@ class ExitNotifyThread(Thread):
     """This class is designed to alert a "monitor" to the fact that a thread has
     exited and to provide for the ability for it to find out why."""
     def run(self):
     """This class is designed to alert a "monitor" to the fact that a thread has
     exited and to provide for the ability for it to find out why."""
     def run(self):
-        global exitcondition, exitthreads, profiledir
+        global exitthreads, profiledir
         self.threadid = thread.get_ident()
         try:
             if not profiledir:          # normal case
         self.threadid = thread.get_ident()
         try:
             if not profiledir:          # normal case
@@ -163,18 +159,18 @@ class ExitNotifyThread(Thread):
                             self.getName() + ".prof")
         except:
             self.setExitCause('EXCEPTION')
                             self.getName() + ".prof")
         except:
             self.setExitCause('EXCEPTION')
-            self.setExitException(sys.exc_info()[1])
-            sbuf = StringIO()
-            traceback.print_exc(file = sbuf)
-            self.setExitStackTrace(sbuf.getvalue())
+            if sys:
+                self.setExitException(sys.exc_info()[1])
+                sbuf = StringIO()
+                traceback.print_exc(file = sbuf)
+                self.setExitStackTrace(sbuf.getvalue())
         else:
             self.setExitCause('NORMAL')
         if not hasattr(self, 'exitmessage'):
             self.setExitMessage(None)
         else:
             self.setExitCause('NORMAL')
         if not hasattr(self, 'exitmessage'):
             self.setExitMessage(None)
-        exitcondition.acquire()
-        exitthreads.append(self)
-        exitcondition.notify()
-        exitcondition.release()
+
+        if exitthreads:
+            exitthreads.put(self, True)
 
     def setExitCause(self, cause):
         self.exitcause = cause
 
     def setExitCause(self, cause):
         self.exitcause = cause
@@ -236,7 +232,8 @@ class InstanceLimitedThread(ExitNotifyThread):
         try:
             ExitNotifyThread.run(self)
         finally:
         try:
             ExitNotifyThread.run(self)
         finally:
-            instancelimitedsems[self.instancename].release()
+            if instancelimitedsems and instancelimitedsems[self.instancename]:
+                instancelimitedsems[self.instancename].release()
         
     
 ######################################################################
         
     
 ######################################################################