diff options
Diffstat (limited to 'src/leap/bitmask/gui')
-rw-r--r-- | src/leap/bitmask/gui/mainwindow.py | 107 |
1 files changed, 50 insertions, 57 deletions
diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index e1527bbe..557f3828 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -21,7 +21,6 @@ import logging import socket import time -from threading import Condition from datetime import datetime from PySide import QtCore, QtGui @@ -93,10 +92,10 @@ class MainWindow(QtGui.QMainWindow): user_stopped_eip = False # We give EIP some time to come up before starting soledad anyway - EIP_TIMEOUT = 60000 # in milliseconds + EIP_START_TIMEOUT = 60000 # in milliseconds - # We give each service some time to come to a halt before forcing quit - SERVICE_STOP_TIMEOUT = 20 + # We give the services some time to a halt before forcing quit. + SERVICES_STOP_TIMEOUT = 20 def __init__(self, quit_callback, bypass_checks=False, start_hidden=False): """ @@ -262,9 +261,6 @@ class MainWindow(QtGui.QMainWindow): # XXX should connect to mail_conductor.start_mail_service instead self.soledad_ready.connect(self._start_smtp_bootstrapping) self.soledad_ready.connect(self._start_imap_service) - self.logout.connect(self._stop_imap_service) - self.logout.connect(self._stop_smtp_service) - ################################# end Qt Signals connection ######## init_platform() @@ -282,6 +278,8 @@ class MainWindow(QtGui.QMainWindow): self._mail_conductor = mail_conductor.MailConductor(self._backend) self._mail_conductor.connect_mail_signals(self._mail_status) + self.logout.connect(self._mail_conductor.stop_mail_services) + # Eip machine is a public attribute where the state machine for # the eip connection will be available to the different components. # Remember that this will not live in the +1600LOC mainwindow for @@ -1441,17 +1439,6 @@ class MainWindow(QtGui.QMainWindow): if self._provides_mx_and_enabled(): self._mail_conductor.start_smtp_service(download_if_needed=True) - # XXX --- should remove from here, and connecte directly to the state - # machine. - @QtCore.Slot() - def _stop_smtp_service(self): - """ - TRIGGERS: - self.logout - """ - # TODO call stop_mail_service - self._mail_conductor.stop_smtp_service() - ################################################################### # Service control methods: imap @@ -1478,20 +1465,6 @@ class MainWindow(QtGui.QMainWindow): if self._provides_mx_and_enabled(): start_fun() - @QtCore.Slot() - def _stop_imap_service(self): - """ - TRIGGERS: - self.logout - """ - cv = Condition() - cv.acquire() - # TODO call stop_mail_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) ################################################################### @@ -1840,7 +1813,7 @@ class MainWindow(QtGui.QMainWindow): # we want to start soledad anyway after a certain timeout if eip # fails to come up QtCore.QTimer.singleShot( - self.EIP_TIMEOUT, + self.EIP_START_TIMEOUT, self._maybe_run_soledad_setup_checks) else: if not self._already_started_eip: @@ -2015,25 +1988,20 @@ class MainWindow(QtGui.QMainWindow): # cleanup and quit methods # - def _cleanup_pidfiles(self): + def _stop_services(self): """ - Removes lockfiles on a clean shutdown. - - Triggered after aboutToQuit signal. + Stop services and cancel ongoing actions (if any). """ - if IS_WIN: - WindowsLock.release_all_locks() + logger.debug('About to quit, doing cleanup.') - def _cleanup_and_quit(self): - """ - Call all the cleanup actions in a serialized way. - Should be called from the quit function. - """ - logger.debug('About to quit, doing cleanup...') + self._cancel_ongoing_defers() - self._stop_imap_service() + logger.debug('Stopping mail services') + self._backend.stop_imap_service() + self._backend.stop_smtp_service() if self._logged_user is not None: + logger.debug("Doing logout") self._backend.logout() logger.debug('Terminating vpn') @@ -2042,7 +2010,8 @@ class MainWindow(QtGui.QMainWindow): # We need to give some time to the ongoing signals for shutdown # to come into action. This needs to be solved using # back-communication from backend. - QtCore.QTimer.singleShot(3000, self._shutdown) + # TODO: handle this, I commented this fix to merge 'cleanly' + # QtCore.QTimer.singleShot(3000, self._shutdown) def _shutdown(self): """ @@ -2061,7 +2030,8 @@ class MainWindow(QtGui.QMainWindow): def quit(self): """ - Cleanup and tidely close the main window before quitting. + Start the quit sequence and wait for services to finish. + Cleanup and close the main window before quitting. """ # TODO separate the shutting down of services from the # UI stuff. @@ -2074,22 +2044,45 @@ class MainWindow(QtGui.QMainWindow): self.tr('The app is quitting, please wait.')) # explicitly process events to display tooltip immediately - QtCore.QCoreApplication.processEvents() + QtCore.QCoreApplication.processEvents(0, 10) + + # Close other windows if any. + if self._wizard: + self._wizard.close() + + if self._logger_window: + self._logger_window.close() # Set this in case that the app is hidden QtGui.QApplication.setQuitOnLastWindowClosed(True) - self._cleanup_and_quit() + self._stop_services() - # We queue the call to stop since we need to wait until EIP is stopped. - # Otherwise we may exit leaving an unmanaged openvpn process. - reactor.callLater(0, self._backend.stop) self._really_quit = True - if self._wizard: - self._wizard.close() + # call final_quit when imap is stopped + self._backend.signaler.imap_stopped.connect(self.final_quit) + # or if we reach the timeout + reactor.callLater(self.SERVICES_STOP_TIMEOUT, self._backend.stop) - if self._logger_window: - self._logger_window.close() + @QtCore.Slot() + def final_quit(self): + """ + Final steps to quit the app, starting from here we don't care about + running services or user interaction, just quitting. + """ + logger.debug('Final quit...') + + try: + # disconnect signal if we get here due a timeout. + self._backend.signaler.imap_stopped.disconnect(self.final_quit) + except RuntimeError: + pass # Signal was not connected + + # Remove lockfiles on a clean shutdown. + logger.debug('Cleaning pidfiles') + if IS_WIN: + WindowsLock.release_all_locks() + self._backend.stop() self.close() |