Showing the changes to interface/src/Application.cpp (1 of 71 files). Show all
Unified · Split
| @@ -48,6 +48,7 @@ · 47 unmodified lines | ||
| 48 | 48 | |
| 49 | 49 | #include <gl/QOpenGLContextWrapper.h> |
| 50 | 50 | |
| 51 | +#include <shared/QtHelpers.h> | |
| 51 | 52 | #include <shared/GlobalAppProperties.h> |
| 52 | 53 | #include <StatTracker.h> |
| 53 | 54 | #include <Trace.h> |
| @@ -1209,15 +1210,26 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 1155 unmodified lines | ||
| 1209 | 1210 | // Make sure we don't time out during slow operations at startup |
| 1210 | 1211 | updateHeartbeat(); |
| 1211 | 1212 | |
| 1212 | − int SAVE_SETTINGS_INTERVAL = 10 * MSECS_PER_SECOND; // Let's save every seconds for now | |
| 1213 | − connect(&_settingsTimer, &QTimer::timeout, this, &Application::saveSettings); | |
| 1214 | − connect(&_settingsThread, SIGNAL(started()), &_settingsTimer, SLOT(start())); | |
| 1215 | − connect(&_settingsThread, SIGNAL(finished()), &_settingsTimer, SLOT(stop())); | |
| 1216 | − _settingsTimer.moveToThread(&_settingsThread); | |
| 1217 | − _settingsTimer.setSingleShot(false); | |
| 1218 | − _settingsTimer.setInterval(SAVE_SETTINGS_INTERVAL); // 10s, Qt::CoarseTimer acceptable | |
| 1219 | − _settingsThread.setPriority(QThread::LowestPriority); | |
| 1220 | − _settingsThread.start(); | |
| 1213 | + | |
| 1214 | + QTimer* settingsTimer = new QTimer(); | |
| 1215 | + moveToNewNamedThread(settingsTimer, "Settings Thread", [this, settingsTimer]{ | |
| 1216 | + connect(qApp, &Application::beforeAboutToQuit, [this, settingsTimer]{ | |
| 1217 | + // Disconnect the signal from the save settings | |
| 1218 | + QObject::disconnect(settingsTimer, &QTimer::timeout, this, &Application::saveSettings); | |
| 1219 | + // Stop the settings timer | |
| 1220 | + settingsTimer->stop(); | |
| 1221 | + // Delete it (this will trigger the thread destruction | |
| 1222 | + settingsTimer->deleteLater(); | |
| 1223 | + // Mark the settings thread as finished, so we know we can safely save in the main application | |
| 1224 | + // shutdown code | |
| 1225 | + _settingsGuard.trigger(); | |
| 1226 | + }); | |
| 1227 | + | |
| 1228 | + int SAVE_SETTINGS_INTERVAL = 10 * MSECS_PER_SECOND; // Let's save every seconds for now | |
| 1229 | + settingsTimer->setSingleShot(false); | |
| 1230 | + settingsTimer->setInterval(SAVE_SETTINGS_INTERVAL); // 10s, Qt::CoarseTimer acceptable | |
| 1231 | + QObject::connect(settingsTimer, &QTimer::timeout, this, &Application::saveSettings); | |
| 1232 | + }, QThread::LowestPriority); | |
| 1221 | 1233 | |
| 1222 | 1234 | if (Menu::getInstance()->isOptionChecked(MenuOption::FirstPerson)) { |
| 1223 | 1235 | getMyAvatar()->setBoomLength(MyAvatar::ZOOM_MIN); // So that camera doesn't auto-switch to third person. |
| @@ -1645,7 +1657,7 @@ QString Application::getUserAgent() { · 421 unmodified lines | ||
| 1645 | 1657 | if (QThread::currentThread() != thread()) { |
| 1646 | 1658 | QString userAgent; |
| 1647 | 1659 | |
| 1648 | − QMetaObject::invokeMethod(this, "getUserAgent", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QString, userAgent)); | |
| 1660 | + BLOCKING_INVOKE_METHOD(this, "getUserAgent", Q_RETURN_ARG(QString, userAgent)); | |
| 1649 | 1661 | |
| 1650 | 1662 | return userAgent; |
| 1651 | 1663 | } |
| @@ -1803,11 +1815,13 @@ void Application::cleanupBeforeQuit() { · 151 unmodified lines | ||
| 1803 | 1815 | locationUpdateTimer.stop(); |
| 1804 | 1816 | identityPacketTimer.stop(); |
| 1805 | 1817 | pingTimer.stop(); |
| 1806 | − QMetaObject::invokeMethod(&_settingsTimer, "stop", Qt::BlockingQueuedConnection); | |
| 1807 | 1818 | |
| 1808 | − // save state | |
| 1809 | − _settingsThread.quit(); | |
| 1810 | − saveSettings(); | |
| 1819 | + // Wait for the settings thread to shut down, and save the settings one last time when it's safe | |
| 1820 | + if (_settingsGuard.wait()) { | |
| 1821 | + // save state | |
| 1822 | + saveSettings(); | |
| 1823 | + } | |
| 1824 | + | |
| 1811 | 1825 | _window->saveGeometry(); |
| 1812 | 1826 | |
| 1813 | 1827 | // Destroy third party processes after scripts have finished using them. |
| @@ -1831,8 +1845,7 @@ void Application::cleanupBeforeQuit() { · 17 unmodified lines | ||
| 1831 | 1845 | |
| 1832 | 1846 | // FIXME: something else is holding a reference to AudioClient, |
| 1833 | 1847 | // so it must be explicitly synchronously stopped here |
| 1834 | − QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), | |
| 1835 | − "cleanupBeforeQuit", Qt::BlockingQueuedConnection); | |
| 1848 | + DependencyManager::get<AudioClient>()->cleanupBeforeQuit(); | |
| 1836 | 1849 | |
| 1837 | 1850 | // destroy Audio so it and its threads have a chance to go down safely |
| 1838 | 1851 | // this must happen after QML, as there are unexplained audio crashes originating in qtwebengine |