summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorisanae <14251494+isanae@users.noreply.github.com>2019-11-06 06:50:05 -0500
committerisanae <14251494+isanae@users.noreply.github.com>2019-11-06 07:45:03 -0500
commit8f40ec0bdcb99cc1a0a2bde3074842391844f5d6 (patch)
treecb27da55c4860a4140174d52a8f982e2da5037de /src
parent96cc662b187f465713d3963f7c8cf9a1b4856aa5 (diff)
threaded wait for process
Diffstat (limited to 'src')
-rw-r--r--src/lockwidget.cpp22
-rw-r--r--src/lockwidget.h5
-rw-r--r--src/processrunner.cpp42
3 files changed, 53 insertions, 16 deletions
diff --git a/src/lockwidget.cpp b/src/lockwidget.cpp
index aae0316b..8b654674 100644
--- a/src/lockwidget.cpp
+++ b/src/lockwidget.cpp
@@ -305,24 +305,38 @@ private:
LockWidget::Session::~Session()
{
- LockWidget::instance().unlock(this);
+ unlock();
+}
+
+void LockWidget::Session::unlock()
+{
+ QMetaObject::invokeMethod(qApp, [this]{
+ LockWidget::instance().unlock(this);
+ });
}
void LockWidget::Session::setInfo(DWORD pid, const QString& name)
{
- m_pid = pid;
- m_name = name;
+ {
+ std::scoped_lock lock(m_mutex);
+ m_pid = pid;
+ m_name = name;
+ }
- LockWidget::instance().updateLabel();
+ QMetaObject::invokeMethod(qApp, [this]{
+ LockWidget::instance().updateLabel();
+ });
}
DWORD LockWidget::Session::pid() const
{
+ std::scoped_lock lock(m_mutex);
return m_pid;
}
const QString& LockWidget::Session::name() const
{
+ std::scoped_lock lock(m_mutex);
return m_name;
}
diff --git a/src/lockwidget.h b/src/lockwidget.h
index 8062c478..640d0076 100644
--- a/src/lockwidget.h
+++ b/src/lockwidget.h
@@ -1,6 +1,7 @@
#pragma once
#include <QMainWindow>
+#include <mutex>
class LockInterface;
@@ -47,6 +48,7 @@ public:
public:
~Session();
+ void unlock();
void setInfo(DWORD pid, const QString& name);
Results result() const;
@@ -54,6 +56,7 @@ public:
const QString& name() const;
private:
+ mutable std::mutex m_mutex;
DWORD m_pid;
QString m_name;
};
@@ -76,7 +79,7 @@ private:
QWidget* m_parent;
std::unique_ptr<LockInterface> m_ui;
std::vector<std::weak_ptr<Session>> m_sessions;
- Results m_result;
+ std::atomic<Results> m_result;
std::vector<QPointer<QWidget>> m_disabled;
void createUi(Reasons reason);
diff --git a/src/processrunner.cpp b/src/processrunner.cpp
index d97c00ef..68acca92 100644
--- a/src/processrunner.cpp
+++ b/src/processrunner.cpp
@@ -55,11 +55,7 @@ std::optional<ProcessRunner::Results> singleWait(HANDLE handle, DWORD pid)
return ProcessRunner::Error;
}
- const DWORD WAIT_EVENT = WAIT_OBJECT_0 + 1;
-
- // Wait for a an event on the handle, a key press, mouse click or timeout
- const auto res = MsgWaitForMultipleObjects(
- 1, &handle, FALSE, 50, QS_KEY | QS_MOUSEBUTTON);
+ const auto res = WaitForSingleObject(handle, 50);
switch (res)
{
@@ -70,7 +66,6 @@ std::optional<ProcessRunner::Results> singleWait(HANDLE handle, DWORD pid)
}
case WAIT_TIMEOUT:
- case WAIT_EVENT:
{
// still running
return {};
@@ -216,10 +211,6 @@ std::optional<ProcessRunner::Results> timedWait(
// the process is still running
- // keep processing events so the app doesn't appear dead
- QCoreApplication::sendPostedEvents();
- QCoreApplication::processEvents();
-
// check the lock widget
switch (ls.result())
{
@@ -263,7 +254,7 @@ std::optional<ProcessRunner::Results> timedWait(
}
}
-ProcessRunner::Results waitForProcesses(
+ProcessRunner::Results waitForProcessesThreadImpl(
const std::vector<HANDLE>& initialProcesses, LockWidget::Session& ls)
{
using namespace std::chrono;
@@ -322,6 +313,35 @@ ProcessRunner::Results waitForProcesses(
}
}
+void waitForProcessesThread(
+ ProcessRunner::Results& result,
+ const std::vector<HANDLE>& initialProcesses, LockWidget::Session& ls)
+{
+ result = waitForProcessesThreadImpl(initialProcesses, ls);
+ ls.unlock();
+}
+
+ProcessRunner::Results waitForProcesses(
+ const std::vector<HANDLE>& initialProcesses, LockWidget::Session& ls)
+{
+ auto results = ProcessRunner::Running;
+
+ auto* t = QThread::create(
+ waitForProcessesThread, std::ref(results), initialProcesses, std::ref(ls));
+
+ QEventLoop events;
+ QObject::connect(t, &QThread::finished, [&]{
+ events.quit();
+ });
+
+ t->start();
+ events.exec();
+
+ delete t;
+
+ return results;
+}
+
ProcessRunner::Results waitForProcess(
HANDLE initialProcess, LPDWORD exitCode, LockWidget::Session& ls)
{