Commit 225dbc57 authored by Luci Stanescu's avatar Luci Stanescu

Added auxiliary thread for blocking operations

parent ab2e0f79
......@@ -10,6 +10,7 @@ __date__ = 'July 5, 2010'
import sys
from PyQt4.QtCore import QThread
from PyQt4.QtGui import QApplication
from application import log
from application.notification import IObserver, NotificationCenter
......@@ -31,6 +32,26 @@ from blink.update import UpdateManager
from blink.util import QSingleton, run_in_gui_thread
class AuxiliaryThread(QThread):
def __init__(self, parent=None):
super(AuxiliaryThread, self).__init__(parent)
self.moveToThread(self)
def run(self):
self.exec_()
def customEvent(self, event):
handler = getattr(self, '_EH_%s' % event.name, Null)
handler(event)
def _EH_CallFunctionEvent(self, event):
try:
event.function(*event.args, **event.kw)
except:
log.error('Exception occured while calling function %s in the auxiliary thread' % event.function.__name__)
log.err()
class Blink(QApplication):
__metaclass__ = QSingleton
......@@ -39,6 +60,7 @@ class Blink(QApplication):
def __init__(self):
super(Blink, self).__init__(sys.argv)
self.application = SIPApplication()
self.auxiliary_thread = AuxiliaryThread()
self.main_window = MainWindow()
self.update_manager = UpdateManager()
......@@ -54,6 +76,7 @@ class Blink(QApplication):
def run(self):
from blink.util import call_in_gui_thread as call_later
call_later(self._initialize_sipsimple)
self.auxiliary_thread.start()
self.exec_()
self.update_manager.shutdown()
self.application.stop()
......
......@@ -17,7 +17,6 @@ from PyQt4.QtGui import QAction, QKeyEvent, QListView, QMenu, QMouseEvent, QReg
from application.notification import IObserver, NotificationCenter
from application.python.decorator import decorator, preserve_signature
from application.python.queue import EventQueue
from application.python.util import Null
from application.system import unlink
from functools import partial
......@@ -29,7 +28,7 @@ from sipsimple.util import makedirs
from blink.resources import ApplicationData, Resources, IconCache
from blink.sessions import SessionManager
from blink.util import run_in_gui_thread
from blink.util import run_in_auxiliary_thread, run_in_gui_thread
from blink.widgets.buttons import SwitchViewButton
......@@ -502,8 +501,6 @@ class ContactModel(QAbstractListModel):
# emulate beginResetModel/endResetModel for QT < 4.6
self.beginResetModel = Null # or use self.modelAboutToBeReset.emit (it'll be emited twice though in that case)
self.endResetModel = self.reset
self.save_queue = EventQueue(self._store_contacts, name='ContactsSavingThread')
self.save_queue.start()
self.bonjour_group = None
notification_center = NotificationCenter()
......@@ -774,6 +771,7 @@ class ContactModel(QAbstractListModel):
self.endRemoveRows()
return items
@run_in_auxiliary_thread
def _store_contacts(self, data):
makedirs(ApplicationData.directory)
filename = ApplicationData.get('contacts')
......@@ -913,7 +911,7 @@ class ContactModel(QAbstractListModel):
items.remove(self.bonjour_group)
position = items.index(reference) if reference in contact_groups else len(self.items)
items.insert(position, group)
self.save_queue.put(pickle.dumps(items))
self._store_contacts(pickle.dumps(items))
class ContactSearchModel(QSortFilterProxyModel):
......
......@@ -24,7 +24,7 @@ from blink.accounts import AccountModel, ActiveAccountModel
from blink.contacts import BonjourNeighbour, Contact, ContactGroup, ContactEditorDialog, ContactModel, ContactSearchModel
from blink.sessions import SessionManager, SessionModel
from blink.resources import Resources
from blink.util import run_in_gui_thread
from blink.util import call_in_auxiliary_thread, run_in_gui_thread
from blink.widgets.buttons import SwitchViewButton
......@@ -258,22 +258,19 @@ class MainWindow(base_class, ui_class):
session_manager.start_call(name, address, contact=contact, account=BonjourAccount() if isinstance(contact, BonjourNeighbour) else None)
def _SH_AudioAlertDeviceChanged(self, action):
from twisted.internet import reactor
settings = SIPSimpleSettings()
settings.audio.alert_device = action.data().toPyObject()
reactor.callInThread(settings.save)
call_in_auxiliary_thread(settings.save)
def _SH_AudioInputDeviceChanged(self, action):
from twisted.internet import reactor
settings = SIPSimpleSettings()
settings.audio.input_device = action.data().toPyObject()
reactor.callInThread(settings.save)
call_in_auxiliary_thread(settings.save)
def _SH_AudioOutputDeviceChanged(self, action):
from twisted.internet import reactor
settings = SIPSimpleSettings()
settings.audio.output_device = action.data().toPyObject()
reactor.callInThread(settings.save)
call_in_auxiliary_thread(settings.save)
def _SH_BreakConference(self):
active_session = self.session_model.data(self.session_list.selectionModel().selectedIndexes()[0])
......
# Copyright (C) 2010 AG Projects. See LICENSE for details.
#
__all__ = ['QSingleton', 'call_in_gui_thread', 'call_later', 'run_in_gui_thread']
__all__ = ['QSingleton', 'call_in_gui_thread', 'call_later', 'run_in_gui_thread', 'call_in_auxiliary_thread', 'run_in_auxiliary_thread']
from PyQt4.QtCore import QObject, QTimer
from PyQt4.QtGui import QApplication
from application.python.decorator import decorator, preserve_signature
from application.python.util import Singleton
from blink.event import CallFunctionEvent
class QSingleton(Singleton, type(QObject)):
"""A metaclass for making Qt objects singletons"""
......@@ -14,7 +17,6 @@ class QSingleton(Singleton, type(QObject)):
def call_in_gui_thread(function, *args, **kw):
from blink import Blink
from blink.event import CallFunctionEvent
blink = Blink()
blink.postEvent(blink, CallFunctionEvent(function, args, kw))
......@@ -29,9 +31,21 @@ def run_in_gui_thread(func):
@preserve_signature(func)
def wrapper(*args, **kw):
from blink import Blink
from blink.event import CallFunctionEvent
blink = Blink()
blink.postEvent(blink, CallFunctionEvent(func, args, kw))
return wrapper
def call_in_auxiliary_thread(function, *args, **kw):
application = QApplication.instance()
application.postEvent(application.auxiliary_thread, CallFunctionEvent(function, args, kw))
def run_in_auxiliary_thread(func):
@preserve_signature(func)
def wrapper(*args, **kw):
application = QApplication.instance()
application.postEvent(application.auxiliary_thread, CallFunctionEvent(func, args, kw))
return wrapper
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment