summaryrefslogtreecommitdiff
path: root/src/processrunner.cpp
diff options
context:
space:
mode:
authorisanae <14251494+isanae@users.noreply.github.com>2019-12-17 07:47:29 -0500
committerGitHub <noreply@github.com>2019-12-17 07:47:29 -0500
commita4a0e59d8ce7d3f9fbe0806a5621c27932f26314 (patch)
tree37e4a9046a8204cc3b70ae8937aae6dab1d9f167 /src/processrunner.cpp
parent2c7e0e7cb4d8bf5c51f22968a5ffd2366d6bcdf2 (diff)
parent05231eab45f86e3d0d342c429e35c8f7c813ea42 (diff)
Merge pull request #942 from isanae/lock-fixes
Lock fixes
Diffstat (limited to 'src/processrunner.cpp')
-rw-r--r--src/processrunner.cpp55
1 files changed, 38 insertions, 17 deletions
diff --git a/src/processrunner.cpp b/src/processrunner.cpp
index 19aae632..945d61c3 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
@@ -341,12 +344,16 @@ ProcessRunner::Results waitForProcessesThreadImpl(
// processes
wait = std::min(wait * 2, milliseconds(2000));
}
+
+ log::debug("waiting for processes interrupted");
+ return ProcessRunner::ForceUnlocked;
}
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();
}
@@ -370,18 +377,23 @@ ProcessRunner::Results waitForProcesses(
if (!::AssignProcessToJobObject(job.get(), h)) {
const auto e = GetLastError();
- log::error(
- "can't assign process to job to wait for processes, {}",
- formatSystemMessage(e));
+ // this happens when closing MO while multiple processes are running,
+ // so the logging is disabled until it gets fixed
+
+ //log::error(
+ // "can't assign process to job to wait for processes, {}",
+ // formatSystemMessage(e));
// keep going
}
}
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 +403,11 @@ ProcessRunner::Results waitForProcesses(
t->start();
events.exec();
+ if (t->isRunning()) {
+ interrupt = true;
+ t->wait();
+ }
+
delete t;
return results;
@@ -860,11 +877,12 @@ ProcessRunner::Results ProcessRunner::waitForAllUSVFSProcessesWithLock(
auto r = Error;
- withLock([&](auto& ls) {
- for (;;) {
+ for (;;) {
+ withLock([&](auto& ls) {
const auto processes = getRunningUSVFSProcesses();
if (processes.empty()) {
- break;
+ r = Completed;
+ return;
}
r = waitForProcesses(processes, ls);
@@ -875,10 +893,13 @@ ProcessRunner::Results ProcessRunner::waitForAllUSVFSProcessesWithLock(
}
// this process is completed, check for others
- }
+ r = Running;
+ });
- r = Completed;
- });
+ if (r != Running) {
+ break;
+ }
+ }
return r;
}