From 1f2784bfa1c1ce90defa32f13c78afd72c227bfd Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Fri, 28 Sep 2018 22:24:33 +0200 Subject: [PATCH] common: Prepare Quassel::quit() to be used more widely 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 | 17 +++++++++++------ src/common/quassel.h | 24 +++++++++++++++++------- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/common/quassel.cpp b/src/common/quassel.cpp index 9a922a6a..646e8edd 100644 --- a/src/common/quassel.cpp +++ b/src/common/quassel.cpp @@ -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(); + } } } } diff --git a/src/common/quassel.h b/src/common/quassel.h index 17e252c1..157386a8 100644 --- a/src/common/quassel.h +++ b/src/common/quassel.h @@ -198,10 +198,26 @@ public: using QuitHandler = std::function; + /** + * 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; -- 2.20.1