From e4c80d78567d79ff0ad4be8e15629e9ed93259bb Mon Sep 17 00:00:00 2001 From: drebs Date: Thu, 6 Feb 2014 15:39:14 -0200 Subject: Ensure IMAP flushes data to disk before quitting. Closes #5095. --- .../feature_5095_ensure-imap-flushes-data-before-quitting | 1 + src/leap/bitmask/gui/mainwindow.py | 14 +++++++++++--- src/leap/bitmask/services/mail/conductor.py | 14 ++++++++++++-- 3 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 changes/feature_5095_ensure-imap-flushes-data-before-quitting diff --git a/changes/feature_5095_ensure-imap-flushes-data-before-quitting b/changes/feature_5095_ensure-imap-flushes-data-before-quitting new file mode 100644 index 00000000..ef1f2888 --- /dev/null +++ b/changes/feature_5095_ensure-imap-flushes-data-before-quitting @@ -0,0 +1 @@ +- Ensure IMAP flushes data to disk before quitting. Closes #5095. diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 86fc1022..db24a1c8 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -19,6 +19,7 @@ Main window for Bitmask. """ import logging +from threading import Condition from PySide import QtCore, QtGui from datetime import datetime from twisted.internet import threads @@ -112,6 +113,9 @@ class MainWindow(QtGui.QMainWindow): # We give EIP some time to come up before starting soledad anyway EIP_TIMEOUT = 60000 # in milliseconds + # We give each service some time to come to a halt before forcing quit + SERVICE_STOP_TIMEOUT = 20 + def __init__(self, quit_callback, openvpn_verb=1, bypass_checks=False): @@ -1330,8 +1334,13 @@ class MainWindow(QtGui.QMainWindow): TRIGGERS: self.logout """ + cv = Condition() + cv.acquire() # TODO call stop_mail_service - self._mail_conductor.stop_imap_service() + threads.deferToThread(self._mail_conductor.stop_imap_service, cv) + # and wait for it to be stopped + logger.debug('Waiting for imap service to stop.') + cv.wait(self.SERVICE_STOP_TIMEOUT) # end service control methods (imap) @@ -1857,7 +1866,7 @@ class MainWindow(QtGui.QMainWindow): """ logger.debug('About to quit, doing cleanup...') - self._mail_conductor.stop_imap_service() + self._stop_imap_service() if self._srp_auth is not None: if self._srp_auth.get_session_id() is not None or \ @@ -1899,7 +1908,6 @@ class MainWindow(QtGui.QMainWindow): self._backend.stop() self._cleanup_and_quit() - self._really_quit = True if self._wizard: diff --git a/src/leap/bitmask/services/mail/conductor.py b/src/leap/bitmask/services/mail/conductor.py index fc53923c..f5892468 100644 --- a/src/leap/bitmask/services/mail/conductor.py +++ b/src/leap/bitmask/services/mail/conductor.py @@ -95,9 +95,13 @@ class IMAPControl(object): logger.debug("Starting loop") self.imap_service.start_loop() - def stop_imap_service(self): + def stop_imap_service(self, cv): """ Stops imap service (fetcher, factory and port). + + :param cv: A condition variable to which we can signal when imap + indeed stops. + :type cv: threading.Condition """ self.imap_connection.qtsigs.disconnecting_signal.emit() # TODO We should homogenize both services. @@ -110,7 +114,13 @@ class IMAPControl(object): self.imap_port.stopListening() # Stop the protocol self.imap_factory.theAccount.closed = True - self.imap_factory.doStop() + self.imap_factory.doStop(cv) + else: + # main window does not have to wait because there's no service to + # be stopped, so we release the condition variable + cv.acquire() + cv.notify() + cv.release() def fetch_incoming_mail(self): """ -- cgit v1.2.3