diff options
author | Saturneric <[email protected]> | 2023-02-18 11:27:19 +0000 |
---|---|---|
committer | Saturneric <[email protected]> | 2023-02-18 11:27:19 +0000 |
commit | 6bfbd9b12911025bebc41b715667ba1cd6863c25 (patch) | |
tree | 9099a5c04319bc6c5ea912847b11ff3e15f36d9c | |
parent | fix: improve the task execution model (diff) | |
download | GpgFrontend-6bfbd9b12911025bebc41b715667ba1cd6863c25.tar.gz GpgFrontend-6bfbd9b12911025bebc41b715667ba1cd6863c25.zip |
feat: implement concurrent task in a proper way
-rw-r--r-- | src/core/thread/Task.cpp | 16 | ||||
-rw-r--r-- | src/core/thread/TaskRunner.cpp | 49 |
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); } |