diff options
Diffstat (limited to 'src/core/thread/TaskRunner.cpp')
-rw-r--r-- | src/core/thread/TaskRunner.cpp | 112 |
1 files changed, 77 insertions, 35 deletions
diff --git a/src/core/thread/TaskRunner.cpp b/src/core/thread/TaskRunner.cpp index f70b2d4c..461d5fb5 100644 --- a/src/core/thread/TaskRunner.cpp +++ b/src/core/thread/TaskRunner.cpp @@ -26,32 +26,24 @@ #include "core/thread/TaskRunner.h" -#include <exception> - #include "core/thread/Task.h" -#include "easylogging++.h" +#include "spdlog/spdlog.h" GpgFrontend::Thread::TaskRunner::TaskRunner() = default; GpgFrontend::Thread::TaskRunner::~TaskRunner() = default; void GpgFrontend::Thread::TaskRunner::PostTask(Task* task) { - std::string uuid = task->GetUUID(); - LOG(TRACE) << "Post Task" << uuid; + if (task == nullptr) { + SPDLOG_ERROR("task posted is null"); + return; + } + + SPDLOG_TRACE("post task: {}", task->GetFullID()); - if (task == nullptr) return; task->setParent(nullptr); task->moveToThread(this); - connect(task, &Task::SignalTaskPostFinishedDone, this, [&, uuid]() { - auto it = pending_tasks_.find(uuid); - if (it == pending_tasks_.end()) { - return; - } else { - it->second->deleteLater(); - pending_tasks_.erase(it); - } - }); { std::lock_guard<std::mutex> lock(tasks_mutex_); tasks.push(task); @@ -59,16 +51,20 @@ void GpgFrontend::Thread::TaskRunner::PostTask(Task* task) { quit(); } -void GpgFrontend::Thread::TaskRunner::run() { - LOG(TRACE) << "called" - << "thread id:" << QThread::currentThreadId(); +void GpgFrontend::Thread::TaskRunner::PostScheduleTask(Task* task, + size_t seconds) { + if (task == nullptr) return; + // TODO +} + +[[noreturn]] void GpgFrontend::Thread::TaskRunner::run() { + SPDLOG_TRACE("task runner runing, thread id: {}", QThread::currentThreadId()); while (true) { - LOG(TRACE) << "TaskRunner: A new cycle start"; if (tasks.empty()) { - LOG(TRACE) << "TaskRunner: No tasks to run, trapping into event loop..."; + SPDLOG_TRACE("no tasks to run, trapping into event loop..."); exec(); } else { - LOG(TRACE) << "TaskRunner: Task queue size:" << tasks.size(); + SPDLOG_TRACE("start to run task(s), queue size: {}", tasks.size()); Task* task = nullptr; { @@ -79,26 +75,72 @@ void GpgFrontend::Thread::TaskRunner::run() { } if (task != nullptr) { - // Run the task - LOG(TRACE) << "TaskRunner: Running Task" << task->GetUUID(); try { + // triger + SPDLOG_TRACE("running task {}, sequency: {}", task->GetFullID(), + task->GetSequency()); + + // when a signal SignalTaskEnd raise, do unregister work + connect(task, &Task::SignalTaskEnd, this, [this, task]() { + unregister_finished_task(task->GetUUID()); + }); + + 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(); } catch (const std::exception& e) { - LOG(ERROR) << "TaskRunner: Exception in Task" << task->GetUUID() - << "Exception: " << e.what(); - - // destroy the task, remove the task from the pending tasks - task->deleteLater(); - pending_tasks_.erase(task->GetUUID()); + SPDLOG_ERROR("task runner: exception in task {}, exception: {}", + task->GetFullID(), e.what()); + // if any exception caught, destroy the task, remove the task from the + // pending tasks + unregister_finished_task(task->GetUUID()); } catch (...) { - LOG(ERROR) << "TaskRunner: Unknwon Exception in Task" - << task->GetUUID(); - - // destroy the task, remove the task from the pending tasks - task->deleteLater(); - pending_tasks_.erase(task->GetUUID()); + SPDLOG_ERROR("task runner: unknown exception in task: {}", + task->GetFullID()); + // if any exception caught, destroy the task, remove the task from the + // pending tasks + unregister_finished_task(task->GetUUID()); } } } } } + +/** + * @brief + * + */ +void GpgFrontend::Thread::TaskRunner::unregister_finished_task( + std::string task_uuid) { + SPDLOG_DEBUG("cleaning task {}", task_uuid); + // search in map + auto pending_task = pending_tasks_.find(task_uuid); + if (pending_task == pending_tasks_.end()) { + SPDLOG_ERROR("cannot find task in pending list: {}", task_uuid); + return; + } else { + std::lock_guard<std::mutex> lock(tasks_mutex_); + // 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); + } + + SPDLOG_DEBUG("clean task {} done", task_uuid); +} |