common: Prepare Quassel::quit() to be used more widely
authorManuel Nickschas <sputnick@quassel-irc.org>
Fri, 28 Sep 2018 20:24:33 +0000 (22:24 +0200)
committerManuel Nickschas <sputnick@quassel-irc.org>
Mon, 1 Oct 2018 17:06:49 +0000 (19:06 +0200)
In the future we want to use Quassel::quit() as the central entry
point for cleanly quitting the application, instead of relying
on QCoreApplication::quit(), which directly stops the event loop
and thus won't process any asynchronous cleanup tasks.

Make the slot public, and protect against multiple invocations.

src/common/quassel.cpp
src/common/quassel.h

index 9a922a6..646e8ed 100644 (file)
@@ -136,12 +136,17 @@ void Quassel::registerQuitHandler(QuitHandler handler)
 
 void Quassel::quit()
 {
-    if (_quitHandlers.empty()) {
-        QCoreApplication::quit();
-    }
-    else {
-        for (auto &&handler : _quitHandlers) {
-            handler();
+    // Protect against multiple invocations (e.g. triggered by MainWin::closeEvent())
+    if (!_quitting) {
+        _quitting = true;
+        if (_quitHandlers.empty()) {
+            QCoreApplication::quit();
+        }
+        else {
+            // Note: We expect one of the registered handlers to call QCoreApplication::quit()
+            for (auto &&handler : _quitHandlers) {
+                handler();
+            }
         }
     }
 }
index 17e252c..157386a 100644 (file)
@@ -198,10 +198,26 @@ public:
 
     using QuitHandler = std::function<void()>;
 
+    /**
+     * Registers a handler that is called when the application is supposed to quit.
+     *
+     * @note If multiple handlers are registered, they are processed in order of registration.
+     * @note If any handler is registered, quit() will not call QCoreApplication::quit(). It relies
+     *       on one of the handlers doing so, instead.
+     * @param quitHandler Handler to register
+     */
     static void registerQuitHandler(QuitHandler quitHandler);
 
     const QString &coreDumpFileName();
 
+public slots:
+    /**
+     * Requests to quit the application.
+     *
+     * Calls any registered quit handlers. If no handlers are registered, calls QCoreApplication::quit().
+     */
+    void quit();
+
 signals:
     void messageLogged(const QDateTime &timeStamp, const QString &msg);
 
@@ -232,13 +248,6 @@ private:
      */
     bool reloadConfig();
 
-    /**
-     * Requests to quit the application.
-     *
-     * Calls any registered quit handlers. If no handlers are registered, calls QCoreApplication::quit().
-     */
-    void quit();
-
     void logBacktrace(const QString &filename);
 
     static void handleSignal(int signal);
@@ -248,6 +257,7 @@ private:
     RunMode _runMode;
     bool _initialized{false};
     bool _handleCrashes{true};
+    bool _quitting{false};
 
     QString _coreDumpFileName;
     QString _configDirPath;