diff options
| author | isanae <14251494+isanae@users.noreply.github.com> | 2019-12-15 21:56:50 -0500 |
|---|---|---|
| committer | isanae <14251494+isanae@users.noreply.github.com> | 2019-12-15 21:56:50 -0500 |
| commit | f3c5cebb6e9262625105d4339a54a810d7816811 (patch) | |
| tree | f8a241de842327e80581b504a042f93d79e4d0e8 /src | |
| parent | dcf88361d49da262acaac335d1317a5d7ef42ded (diff) | |
fixed exiting before QThread joins when pressing the X twice
Diffstat (limited to 'src')
| -rw-r--r-- | src/mainwindow.cpp | 21 | ||||
| -rw-r--r-- | src/processrunner.cpp | 31 | ||||
| -rw-r--r-- | src/shared/util.cpp | 11 | ||||
| -rw-r--r-- | src/shared/util.h | 1 |
4 files changed, 46 insertions, 18 deletions
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index a29ea8ab..d1578d85 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1317,18 +1317,25 @@ void MainWindow::closeEvent(QCloseEvent* event) // // for 2), the settings have been saved and the window can just close - if (ModOrganizerExiting()) { + if (ModOrganizerCanCloseNow()) { // the user has confirmed if necessary and all settings have been saved, // just close it QMainWindow::closeEvent(event); - } else { - // never close the window because settings might need to be changed - event->ignore(); + return; + } - // start the process of exiting, which may require confirmation by calling - // canExit(), among other things - ExitModOrganizer(); + if (ModOrganizerExiting()) { + // ignore repeated attempts + event->ignore(); + return; } + + // never close the window because settings might need to be changed + event->ignore(); + + // start the process of exiting, which may require confirmation by calling + // canExit(), among other things + ExitModOrganizer(); } bool MainWindow::canExit() diff --git a/src/processrunner.cpp b/src/processrunner.cpp index 19aae632..aead42d1 100644 --- a/src/processrunner.cpp +++ b/src/processrunner.cpp @@ -225,7 +225,7 @@ const std::chrono::milliseconds Infinite(-1); // std::optional<ProcessRunner::Results> timedWait( HANDLE handle, DWORD pid, UILocker::Session& ls, - std::chrono::milliseconds wait) + std::chrono::milliseconds wait, std::atomic<bool>& interrupt) { using namespace std::chrono; @@ -234,7 +234,7 @@ std::optional<ProcessRunner::Results> timedWait( start = high_resolution_clock::now(); } - for (;;) { + while (!interrupt) { // wait for a very short while, allows for processing events below const auto r = singleWait(handle, pid); @@ -286,10 +286,13 @@ std::optional<ProcessRunner::Results> timedWait( } } } + + log::debug("waiting for {} interrupted", pid); + return ProcessRunner::ForceUnlocked; } ProcessRunner::Results waitForProcessesThreadImpl( - HANDLE job, UILocker::Session& ls) + HANDLE job, UILocker::Session& ls, std::atomic<bool>& interrupt) { using namespace std::chrono; @@ -301,7 +304,7 @@ ProcessRunner::Results waitForProcessesThreadImpl( const milliseconds defaultWait(50); auto wait = defaultWait; - for (;;) { + while (!interrupt) { auto ip = getInterestingProcess(job); if (!ip.handle) { // nothing to wait on @@ -325,7 +328,7 @@ ProcessRunner::Results waitForProcessesThreadImpl( wait = Infinite; } - const auto r = timedWait(ip.handle.get(), ip.p.pid(), ls, wait); + const auto r = timedWait(ip.handle.get(), ip.p.pid(), ls, wait, interrupt); if (r) { if (*r == ProcessRunner::Results::Completed) { // process completed, check another one, reset the wait time to find @@ -344,9 +347,10 @@ ProcessRunner::Results waitForProcessesThreadImpl( } void waitForProcessesThread( - ProcessRunner::Results& result, HANDLE job, UILocker::Session& ls) + ProcessRunner::Results& result, HANDLE job, UILocker::Session& ls, + std::atomic<bool>& interrupt) { - result = waitForProcessesThreadImpl(job, ls); + result = waitForProcessesThreadImpl(job, ls, interrupt); ls.unlock(); } @@ -379,9 +383,11 @@ ProcessRunner::Results waitForProcesses( } auto results = ProcessRunner::Running; + std::atomic<bool> interrupt(false); auto* t = QThread::create( - waitForProcessesThread, std::ref(results), job.get(), std::ref(ls)); + waitForProcessesThread, + std::ref(results), job.get(), std::ref(ls), std::ref(interrupt)); QEventLoop events; QObject::connect(t, &QThread::finished, [&]{ @@ -391,6 +397,11 @@ ProcessRunner::Results waitForProcesses( t->start(); events.exec(); + if (t->isRunning()) { + interrupt = true; + t->wait(); + } + delete t; return results; @@ -861,7 +872,7 @@ ProcessRunner::Results ProcessRunner::waitForAllUSVFSProcessesWithLock( auto r = Error; withLock([&](auto& ls) { - for (;;) { + for (;;) { const auto processes = getRunningUSVFSProcesses(); if (processes.empty()) { break; @@ -878,7 +889,7 @@ ProcessRunner::Results ProcessRunner::waitForAllUSVFSProcessesWithLock( } r = Completed; - }); + }); return r; } diff --git a/src/shared/util.cpp b/src/shared/util.cpp index 32eb825c..baceddeb 100644 --- a/src/shared/util.cpp +++ b/src/shared/util.cpp @@ -294,6 +294,7 @@ QString getUsvfsVersionString() static bool g_exiting = false;
+static bool g_canClose = false;
MainWindow* findMainWindow()
{
@@ -312,6 +313,9 @@ bool ExitModOrganizer(ExitFlags e) return true;
}
+ g_exiting = true;
+ MOBase::Guard g([&]{ g_exiting = false; });
+
if (!e.testFlag(Exit::Force)) {
if (auto* mw=findMainWindow()) {
if (!mw->canExit()) {
@@ -320,7 +324,7 @@ bool ExitModOrganizer(ExitFlags e) }
}
- g_exiting = true;
+ g_canClose = true;
const int code = (e.testFlag(Exit::Restart) ? RestartExitCode : 0);
qApp->exit(code);
@@ -328,6 +332,11 @@ bool ExitModOrganizer(ExitFlags e) return true;
}
+bool ModOrganizerCanCloseNow()
+{
+ return g_canClose;
+}
+
bool ModOrganizerExiting()
{
return g_exiting;
diff --git a/src/shared/util.h b/src/shared/util.h index e87244b6..e8a58549 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -65,6 +65,7 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(ExitFlags); bool ExitModOrganizer(ExitFlags e=Exit::Normal);
bool ModOrganizerExiting();
+bool ModOrganizerCanCloseNow();
void ResetExitFlag();
#endif // UTIL_H
|
