aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSaturneric <[email protected]>2023-02-18 11:27:19 +0000
committerSaturneric <[email protected]>2023-02-18 11:27:19 +0000
commit6bfbd9b12911025bebc41b715667ba1cd6863c25 (patch)
tree9099a5c04319bc6c5ea912847b11ff3e15f36d9c
parentfix: improve the task execution model (diff)
downloadGpgFrontend-6bfbd9b12911025bebc41b715667ba1cd6863c25.tar.gz
GpgFrontend-6bfbd9b12911025bebc41b715667ba1cd6863c25.zip
feat: implement concurrent task in a proper way
-rw-r--r--src/core/thread/Task.cpp16
-rw-r--r--src/core/thread/TaskRunner.cpp49
2 files changed, 34 insertions, 31 deletions
diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp
index 937211cf..f3c6ae86 100644
--- a/src/core/thread/Task.cpp
+++ b/src/core/thread/Task.cpp
@@ -160,10 +160,18 @@ void GpgFrontend::Thread::Task::run() {
if (thread() != QThread::currentThread()) {
SPDLOG_DEBUG("task running thread is not object living thread");
- // running in another thread, blocking until returned
- if (!QMetaObject::invokeMethod(thread(), runnable_package,
- Qt::BlockingQueuedConnection)) {
- SPDLOG_ERROR("qt invoke method failed");
+ // if running sequently
+ if (sequency_) {
+ // running in another thread, blocking until returned
+ if (!QMetaObject::invokeMethod(thread(), runnable_package,
+ Qt::BlockingQueuedConnection)) {
+ SPDLOG_ERROR("qt invoke method failed");
+ }
+ } else {
+ // running in another thread, non-blocking
+ if (!QMetaObject::invokeMethod(thread(), runnable_package)) {
+ SPDLOG_ERROR("qt invoke method failed");
+ }
}
} else {
if (!QMetaObject::invokeMethod(this, runnable_package)) {
diff --git a/src/core/thread/TaskRunner.cpp b/src/core/thread/TaskRunner.cpp
index b60a4b89..461d5fb5 100644
--- a/src/core/thread/TaskRunner.cpp
+++ b/src/core/thread/TaskRunner.cpp
@@ -80,37 +80,29 @@ void GpgFrontend::Thread::TaskRunner::PostScheduleTask(Task* task,
SPDLOG_TRACE("running task {}, sequency: {}", task->GetFullID(),
task->GetSequency());
- // run sequently
// when a signal SignalTaskEnd raise, do unregister work
connect(task, &Task::SignalTaskEnd, this, [this, task]() {
unregister_finished_task(task->GetUUID());
});
- // run task
+
+ if (!task->GetSequency()) {
+ // if it need to run concurrently, we should create a new thread to
+ // run it.
+ auto* concurrent_thread = new QThread(nullptr);
+ task->setParent(nullptr);
+ task->moveToThread(concurrent_thread);
+ // start thread
+ concurrent_thread->start();
+
+ connect(task, &Task::SignalTaskEnd, concurrent_thread,
+ &QThread::quit);
+ // concurrent thread is responsible for deleting the task
+ connect(concurrent_thread, &QThread::finished, task,
+ &Task::deleteLater);
+ }
+
+ // run the task
task->run();
- // if (task->GetSequency()) {
-
- // } else {
- // // run concurrently
- // auto* concurrent_thread = new QThread(nullptr);
- // task->setParent(nullptr);
- // task->moveToThread(concurrent_thread);
- // connect(concurrent_thread, &QThread::started, task,
- // &Task::SlotRun); connect(task, &Task::SignalTaskPostFinishedDone,
- // this,
- // [uuid = task->GetUUID(), this]() {
- // unregister_finished_task(uuid);
- // });
- // connect(task, &Task::SignalTaskPostFinishedDone,
- // concurrent_thread,
- // &QThread::quit);
- // connect(concurrent_thread, &QThread::finished, concurrent_thread,
- // [task, concurrent_thread]() {
- // task->deleteLater();
- // concurrent_thread->deleteLater();
- // });
- // // start thread
- // concurrent_thread->start();
- // }
} catch (const std::exception& e) {
SPDLOG_ERROR("task runner: exception in task {}, exception: {}",
task->GetFullID(), e.what());
@@ -143,7 +135,10 @@ void GpgFrontend::Thread::TaskRunner::unregister_finished_task(
return;
} else {
std::lock_guard<std::mutex> lock(tasks_mutex_);
- pending_task->second->deleteLater();
+ // if thread runs sequenctly, that means the thread is living in this
+ // thread, so we can delete it. Or, its living thread need to delete it.
+ if (pending_task->second->GetSequency())
+ pending_task->second->deleteLater();
pending_tasks_.erase(pending_task);
}