Use one queue object in FunctionDispatch.

Theory: the producer (Qt GUI cover function) exists only once per instance of FunctionDispatcher. This follows from the fact that the dispatcher instance is created on the recipient thread. The consumer (the cover cache) could in theory be multiple threads (but it isn't). Because the items produced by the producer are not equivalent, we need to ensure that the order of items put in the queue by the producer is equal to the order of the requests. To guarantee this order, regardless of the number of consumer threads, we ensure that only one request to the producer can be outstanding.
This commit is contained in:
Charles Haley 2010-09-21 20:20:34 +01:00
parent 1bfccfa4c4
commit a62ad5f70c

View File

@ -1,7 +1,7 @@
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
""" The GUI """ """ The GUI """
import os, sys, Queue import os, sys, Queue, threading
from threading import RLock from threading import RLock
from PyQt4.Qt import QVariant, QFileInfo, QObject, SIGNAL, QBuffer, Qt, \ from PyQt4.Qt import QVariant, QFileInfo, QObject, SIGNAL, QBuffer, Qt, \
@ -311,11 +311,14 @@ class FunctionDispatcher(QObject):
if not queued: if not queued:
typ = Qt.AutoConnection if queued is None else Qt.DirectConnection typ = Qt.AutoConnection if queued is None else Qt.DirectConnection
self.dispatch_signal.connect(self.dispatch, type=typ) self.dispatch_signal.connect(self.dispatch, type=typ)
self.q = Queue.Queue()
self.lock = threading.Lock()
def __call__(self, *args, **kwargs): def __call__(self, *args, **kwargs):
q = Queue.Queue() with self.lock:
self.dispatch_signal.emit(q, args, kwargs) self.dispatch_signal.emit(self.q, args, kwargs)
return q.get() res = self.q.get()
return res
def dispatch(self, q, args, kwargs): def dispatch(self, q, args, kwargs):
try: try: