From 95997d27106daf91336847f50efaaa32279b7fc7 Mon Sep 17 00:00:00 2001 From: saturneric Date: Mon, 16 Oct 2023 17:54:05 +0800 Subject: fix: check and update copyright at files --- src/core/thread/TaskRunner.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/core/thread/TaskRunner.cpp') diff --git a/src/core/thread/TaskRunner.cpp b/src/core/thread/TaskRunner.cpp index 461d5fb5..35ac561e 100644 --- a/src/core/thread/TaskRunner.cpp +++ b/src/core/thread/TaskRunner.cpp @@ -1,5 +1,5 @@ /** - * Copyright (C) 2021 Saturneric + * Copyright (C) 2021 Saturneric * * This file is part of GpgFrontend. * @@ -19,8 +19,10 @@ * The initial version of the source code is inherited from * the gpg4usb project, which is under GPL-3.0-or-later. * - * The source code version of this software was modified and released - * by Saturneric starting on May 12, 2021. + * All the source code of GpgFrontend was modified and released by + * Saturneric starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later * */ -- cgit v1.2.3 From 76fda183d4c1067ab1735965e9bde3c7b29d1345 Mon Sep 17 00:00:00 2001 From: saturneric Date: Wed, 18 Oct 2023 20:54:02 +0800 Subject: feat: simplify the thread system and improve its stability --- src/core/thread/TaskRunner.cpp | 157 ++++++++++++++--------------------------- 1 file changed, 54 insertions(+), 103 deletions(-) (limited to 'src/core/thread/TaskRunner.cpp') diff --git a/src/core/thread/TaskRunner.cpp b/src/core/thread/TaskRunner.cpp index 35ac561e..6eed7a89 100644 --- a/src/core/thread/TaskRunner.cpp +++ b/src/core/thread/TaskRunner.cpp @@ -28,121 +28,72 @@ #include "core/thread/TaskRunner.h" +#include +#include + +#include + #include "core/thread/Task.h" #include "spdlog/spdlog.h" -GpgFrontend::Thread::TaskRunner::TaskRunner() = default; +namespace GpgFrontend::Thread { -GpgFrontend::Thread::TaskRunner::~TaskRunner() = default; +class TaskRunner::Impl : public QThread { + public: + void PostTask(Task* task) { + if (task == nullptr) { + SPDLOG_ERROR("task posted is null"); + return; + } -void GpgFrontend::Thread::TaskRunner::PostTask(Task* task) { - if (task == nullptr) { - SPDLOG_ERROR("task posted is null"); - return; + task->setParent(nullptr); + connect(task, &Task::SignalTaskEnd, task, &Task::deleteLater); + + if (task->GetSequency()) { + SPDLOG_TRACE("post task: {}, sequency mode: {}", task->GetFullID(), + task->GetSequency()); + task->moveToThread(this); + } else { + // if it need to run concurrently, we should create a new thread to + // run it. + auto* concurrent_thread = new QThread(this); + + connect(task, &Task::SignalTaskEnd, concurrent_thread, &QThread::quit); + // concurrent thread is responsible for deleting the task + connect(concurrent_thread, &QThread::finished, task, &Task::deleteLater); + // concurrent thread is responsible for self deleting + connect(concurrent_thread, &QThread::finished, concurrent_thread, + &QThread::deleteLater); + + // start thread + concurrent_thread->start(); + task->moveToThread(concurrent_thread); + } + emit task->SignalRun(); } - SPDLOG_TRACE("post task: {}", task->GetFullID()); + void PostScheduleTask(Task* task, size_t seconds) { + if (task == nullptr) return; + // TODO + } +}; - task->setParent(nullptr); - task->moveToThread(this); +GpgFrontend::Thread::TaskRunner::TaskRunner() : p_(std::make_unique()) {} - { - std::lock_guard lock(tasks_mutex_); - tasks.push(task); - } - quit(); -} +GpgFrontend::Thread::TaskRunner::~TaskRunner() = default; -void GpgFrontend::Thread::TaskRunner::PostScheduleTask(Task* task, - size_t seconds) { - if (task == nullptr) return; - // TODO +void GpgFrontend::Thread::TaskRunner::PostTask(Task* task) { + p_->PostTask(task); } -[[noreturn]] void GpgFrontend::Thread::TaskRunner::run() { - SPDLOG_TRACE("task runner runing, thread id: {}", QThread::currentThreadId()); - while (true) { - if (tasks.empty()) { - SPDLOG_TRACE("no tasks to run, trapping into event loop..."); - exec(); - } else { - SPDLOG_TRACE("start to run task(s), queue size: {}", tasks.size()); - - Task* task = nullptr; - { - std::lock_guard lock(tasks_mutex_); - task = std::move(tasks.front()); - tasks.pop(); - pending_tasks_.insert({task->GetUUID(), task}); - } - - if (task != nullptr) { - 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) { - 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 (...) { - 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()); - } - } - } - } +void TaskRunner::PostScheduleTask(Task* task, size_t seconds) { + p_->PostScheduleTask(task, seconds); } -/** - * @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 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); - } +void TaskRunner::Start() { p_->start(); } - SPDLOG_DEBUG("clean task {} done", task_uuid); -} +QThread* TaskRunner::GetThread() { return p_.get(); } + +bool TaskRunner::IsRunning() { return p_->isRunning(); } + +} // namespace GpgFrontend::Thread -- cgit v1.2.3 From 70196cf01757824a578e4d9c49a210bf136de266 Mon Sep 17 00:00:00 2001 From: saturneric Date: Wed, 18 Oct 2023 22:45:33 +0800 Subject: feat: using pool for concurrent executions, not stable yet --- src/core/thread/TaskRunner.cpp | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) (limited to 'src/core/thread/TaskRunner.cpp') diff --git a/src/core/thread/TaskRunner.cpp b/src/core/thread/TaskRunner.cpp index 6eed7a89..494e356c 100644 --- a/src/core/thread/TaskRunner.cpp +++ b/src/core/thread/TaskRunner.cpp @@ -30,6 +30,7 @@ #include #include +#include #include @@ -47,27 +48,19 @@ class TaskRunner::Impl : public QThread { } task->setParent(nullptr); - connect(task, &Task::SignalTaskEnd, task, &Task::deleteLater); if (task->GetSequency()) { SPDLOG_TRACE("post task: {}, sequency mode: {}", task->GetFullID(), task->GetSequency()); task->moveToThread(this); } else { - // if it need to run concurrently, we should create a new thread to - // run it. - auto* concurrent_thread = new QThread(this); - - connect(task, &Task::SignalTaskEnd, concurrent_thread, &QThread::quit); - // concurrent thread is responsible for deleting the task - connect(concurrent_thread, &QThread::finished, task, &Task::deleteLater); - // concurrent thread is responsible for self deleting - connect(concurrent_thread, &QThread::finished, concurrent_thread, - &QThread::deleteLater); - - // start thread - concurrent_thread->start(); - task->moveToThread(concurrent_thread); + if (pool_.tryStart(task)) { + SPDLOG_TRACE("runner's pool starts concurrent task {} immediately", + task->GetFullID()); + } else { + SPDLOG_TRACE("runner's pool will start concurrent task {} later", + task->GetFullID()); + } } emit task->SignalRun(); } @@ -76,6 +69,9 @@ class TaskRunner::Impl : public QThread { if (task == nullptr) return; // TODO } + + private: + QThreadPool pool_; }; GpgFrontend::Thread::TaskRunner::TaskRunner() : p_(std::make_unique()) {} -- cgit v1.2.3 From 025c268f91ee1deab17891f00dc8c90c4770224f Mon Sep 17 00:00:00 2001 From: saturneric Date: Thu, 19 Oct 2023 18:51:20 +0800 Subject: fix: improve the stability of thread system --- src/core/thread/TaskRunner.cpp | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) (limited to 'src/core/thread/TaskRunner.cpp') diff --git a/src/core/thread/TaskRunner.cpp b/src/core/thread/TaskRunner.cpp index 494e356c..e8b85e93 100644 --- a/src/core/thread/TaskRunner.cpp +++ b/src/core/thread/TaskRunner.cpp @@ -48,30 +48,36 @@ class TaskRunner::Impl : public QThread { } task->setParent(nullptr); + task->moveToThread(this); - if (task->GetSequency()) { - SPDLOG_TRACE("post task: {}, sequency mode: {}", task->GetFullID(), - task->GetSequency()); - task->moveToThread(this); - } else { - if (pool_.tryStart(task)) { - SPDLOG_TRACE("runner's pool starts concurrent task {} immediately", - task->GetFullID()); - } else { - SPDLOG_TRACE("runner's pool will start concurrent task {} later", - task->GetFullID()); - } + SPDLOG_TRACE("runner's pool starts task: {}", task->GetFullID()); + task->SafelyRun(); + } + + void PostConcurrentTask(Task* task) { + if (task == nullptr) { + SPDLOG_ERROR("task posted is null"); + return; } - emit task->SignalRun(); + + auto* concurrent_thread = new QThread(this); + + task->setParent(nullptr); + task->moveToThread(concurrent_thread); + + connect(task, &Task::SignalTaskEnd, concurrent_thread, &QThread::quit); + connect(concurrent_thread, &QThread::finished, concurrent_thread, + &QThread::deleteLater); + + concurrent_thread->start(); + + task->SafelyRun(); } void PostScheduleTask(Task* task, size_t seconds) { if (task == nullptr) return; // TODO } - - private: - QThreadPool pool_; }; GpgFrontend::Thread::TaskRunner::TaskRunner() : p_(std::make_unique()) {} @@ -82,6 +88,10 @@ void GpgFrontend::Thread::TaskRunner::PostTask(Task* task) { p_->PostTask(task); } +void GpgFrontend::Thread::TaskRunner::PostConcurrentTask(Task* task) { + p_->PostConcurrentTask(task); +} + void TaskRunner::PostScheduleTask(Task* task, size_t seconds) { p_->PostScheduleTask(task, seconds); } -- cgit v1.2.3 From 31fc827672a131da020c4b4a0c3c8a145d477835 Mon Sep 17 00:00:00 2001 From: saturneric Date: Mon, 23 Oct 2023 14:29:25 +0800 Subject: feat: improve project structure and add GRT for modules --- src/core/thread/TaskRunner.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/core/thread/TaskRunner.cpp') diff --git a/src/core/thread/TaskRunner.cpp b/src/core/thread/TaskRunner.cpp index e8b85e93..2035fe67 100644 --- a/src/core/thread/TaskRunner.cpp +++ b/src/core/thread/TaskRunner.cpp @@ -50,7 +50,7 @@ class TaskRunner::Impl : public QThread { task->setParent(nullptr); task->moveToThread(this); - SPDLOG_TRACE("runner's pool starts task: {}", task->GetFullID()); + SPDLOG_TRACE("runner starts task: {}", task->GetFullID()); task->SafelyRun(); } @@ -71,6 +71,7 @@ class TaskRunner::Impl : public QThread { concurrent_thread->start(); + SPDLOG_TRACE("runner starts task concurrenctly: {}", task->GetFullID()); task->SafelyRun(); } -- cgit v1.2.3 From 5a3f422335b27c6c19a2d91f525c77435e8f2384 Mon Sep 17 00:00:00 2001 From: saturneric Date: Mon, 23 Oct 2023 21:23:37 +0800 Subject: fix: solve some issues on log system --- src/core/thread/TaskRunner.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/core/thread/TaskRunner.cpp') diff --git a/src/core/thread/TaskRunner.cpp b/src/core/thread/TaskRunner.cpp index 2035fe67..8250bb5b 100644 --- a/src/core/thread/TaskRunner.cpp +++ b/src/core/thread/TaskRunner.cpp @@ -28,6 +28,7 @@ #include "core/thread/TaskRunner.h" +#include #include #include #include @@ -41,6 +42,11 @@ namespace GpgFrontend::Thread { class TaskRunner::Impl : public QThread { public: + Impl() { + SPDLOG_TRACE("task runner created, thread id: {}", + QThread::currentThread()->currentThreadId()); + } + void PostTask(Task* task) { if (task == nullptr) { SPDLOG_ERROR("task posted is null"); -- cgit v1.2.3 From 124929609eabff19359caad276a10f1026793c0f Mon Sep 17 00:00:00 2001 From: saturneric Date: Wed, 25 Oct 2023 18:26:26 +0800 Subject: fix: solve some code tidy issues --- src/core/thread/TaskRunner.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/core/thread/TaskRunner.cpp') diff --git a/src/core/thread/TaskRunner.cpp b/src/core/thread/TaskRunner.cpp index 8250bb5b..ca6a4033 100644 --- a/src/core/thread/TaskRunner.cpp +++ b/src/core/thread/TaskRunner.cpp @@ -36,7 +36,6 @@ #include #include "core/thread/Task.h" -#include "spdlog/spdlog.h" namespace GpgFrontend::Thread { -- cgit v1.2.3 From fd46d4667611c0db9cea3f06205727399b6fb5fd Mon Sep 17 00:00:00 2001 From: saturneric Date: Sun, 29 Oct 2023 02:46:15 +0800 Subject: refactor: start to tidy up code using clang-tidy --- src/core/thread/TaskRunner.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/core/thread/TaskRunner.cpp') diff --git a/src/core/thread/TaskRunner.cpp b/src/core/thread/TaskRunner.cpp index ca6a4033..86e06dfd 100644 --- a/src/core/thread/TaskRunner.cpp +++ b/src/core/thread/TaskRunner.cpp @@ -33,8 +33,6 @@ #include #include -#include - #include "core/thread/Task.h" namespace GpgFrontend::Thread { -- cgit v1.2.3 From f9a49043c35e73fc2d4ffb3ed9b39c33849c43b3 Mon Sep 17 00:00:00 2001 From: saturneric Date: Fri, 15 Dec 2023 21:14:17 +0800 Subject: fix: slove threading and memory issues --- src/core/thread/TaskRunner.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'src/core/thread/TaskRunner.cpp') diff --git a/src/core/thread/TaskRunner.cpp b/src/core/thread/TaskRunner.cpp index 86e06dfd..88913bc4 100644 --- a/src/core/thread/TaskRunner.cpp +++ b/src/core/thread/TaskRunner.cpp @@ -86,7 +86,11 @@ class TaskRunner::Impl : public QThread { GpgFrontend::Thread::TaskRunner::TaskRunner() : p_(std::make_unique()) {} -GpgFrontend::Thread::TaskRunner::~TaskRunner() = default; +GpgFrontend::Thread::TaskRunner::~TaskRunner() { + if (p_->isRunning()) { + Stop(); + } +} void GpgFrontend::Thread::TaskRunner::PostTask(Task* task) { p_->PostTask(task); @@ -102,8 +106,13 @@ void TaskRunner::PostScheduleTask(Task* task, size_t seconds) { void TaskRunner::Start() { p_->start(); } -QThread* TaskRunner::GetThread() { return p_.get(); } +void TaskRunner::Stop() { + p_->quit(); + p_->wait(); +} + +auto TaskRunner::GetThread() -> QThread* { return p_.get(); } -bool TaskRunner::IsRunning() { return p_->isRunning(); } +auto TaskRunner::IsRunning() -> bool { return p_->isRunning(); } } // namespace GpgFrontend::Thread -- cgit v1.2.3 From 37215a895a649345165027971690dfdcd9106a32 Mon Sep 17 00:00:00 2001 From: saturneric Date: Fri, 15 Dec 2023 21:53:03 -0800 Subject: fix: use secure memory management at impl class --- src/core/thread/TaskRunner.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/core/thread/TaskRunner.cpp') diff --git a/src/core/thread/TaskRunner.cpp b/src/core/thread/TaskRunner.cpp index 88913bc4..a4a97b38 100644 --- a/src/core/thread/TaskRunner.cpp +++ b/src/core/thread/TaskRunner.cpp @@ -84,7 +84,8 @@ class TaskRunner::Impl : public QThread { } }; -GpgFrontend::Thread::TaskRunner::TaskRunner() : p_(std::make_unique()) {} +GpgFrontend::Thread::TaskRunner::TaskRunner() + : p_(SecureCreateUniqueObject()) {} GpgFrontend::Thread::TaskRunner::~TaskRunner() { if (p_->isRunning()) { -- cgit v1.2.3 From 300e55bf5bddc393de050c2ca9a0356fce9a8a9d Mon Sep 17 00:00:00 2001 From: saturneric Date: Thu, 28 Dec 2023 14:32:49 +0800 Subject: feat: add simple archiving functions for encrypt and decrypt --- src/core/thread/TaskRunner.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src/core/thread/TaskRunner.cpp') diff --git a/src/core/thread/TaskRunner.cpp b/src/core/thread/TaskRunner.cpp index a4a97b38..6d5edd93 100644 --- a/src/core/thread/TaskRunner.cpp +++ b/src/core/thread/TaskRunner.cpp @@ -39,10 +39,7 @@ namespace GpgFrontend::Thread { class TaskRunner::Impl : public QThread { public: - Impl() { - SPDLOG_TRACE("task runner created, thread id: {}", - QThread::currentThread()->currentThreadId()); - } + Impl() : QThread(nullptr) {} void PostTask(Task* task) { if (task == nullptr) { @@ -53,7 +50,8 @@ class TaskRunner::Impl : public QThread { task->setParent(nullptr); task->moveToThread(this); - SPDLOG_TRACE("runner starts task: {}", task->GetFullID()); + SPDLOG_TRACE("runner starts task: {} at thread: {}", task->GetFullID(), + this->currentThreadId()); task->SafelyRun(); } -- cgit v1.2.3 From 9f7593eab9b2d6f6fa6d76a303975b355b6ab458 Mon Sep 17 00:00:00 2001 From: saturneric Date: Sat, 30 Dec 2023 19:55:20 +0800 Subject: feat: do not load entire data to memory in libarchive operations --- src/core/thread/TaskRunner.cpp | 83 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 73 insertions(+), 10 deletions(-) (limited to 'src/core/thread/TaskRunner.cpp') diff --git a/src/core/thread/TaskRunner.cpp b/src/core/thread/TaskRunner.cpp index 6d5edd93..72266d20 100644 --- a/src/core/thread/TaskRunner.cpp +++ b/src/core/thread/TaskRunner.cpp @@ -28,10 +28,11 @@ #include "core/thread/TaskRunner.h" -#include -#include -#include -#include +#include +#include +#include +#include +#include #include "core/thread/Task.h" @@ -55,6 +56,61 @@ class TaskRunner::Impl : public QThread { task->SafelyRun(); } + static void PostTask(const Task::TaskRunnable& runner, + const Task::TaskCallback& cb, DataObjectPtr p_obj) { + auto* callback_thread = QThread::currentThread(); + auto data_object = std::move(p_obj); + const auto task_uuid = generate_uuid(); + + QtConcurrent::run(runner, data_object).then([=](int rtn) { + if (!cb) { + SPDLOG_TRACE("task {} doesn't have a callback function", task_uuid); + return; + } + + if (callback_thread == QThread::currentThread()) { + SPDLOG_TRACE("for task {}, the callback thread is the same thread: {}", + task_uuid, static_cast(callback_thread)); + + cb(rtn, data_object); + + // raise signal, announcing this task comes to an end + SPDLOG_TRACE( + "for task {}, its life comes to an end in the same thread " + "after its callback executed.", + task_uuid); + } else { + SPDLOG_TRACE("for task {}, callback thread is a different thread: {}", + task_uuid, static_cast(callback_thread)); + if (!QMetaObject::invokeMethod(callback_thread, [=]() { + SPDLOG_TRACE("calling callback of task {}", task_uuid); + try { + cb(rtn, data_object); + } catch (...) { + SPDLOG_ERROR( + "unknown exception was caught when execute " + "callback of task {}", + task_uuid); + } + // raise signal, announcing this task comes to an end + SPDLOG_TRACE( + "for task {}, its life comes to an end whether its " + "callback function fails or not.", + task_uuid); + })) { + SPDLOG_ERROR( + "task {} had failed to invoke the callback function to " + "target thread", + task_uuid); + SPDLOG_TRACE( + "for task {}, its life must come to an end now, although it " + "has something not done yet.", + task_uuid); + } + } + }); + } + void PostConcurrentTask(Task* task) { if (task == nullptr) { SPDLOG_ERROR("task posted is null"); @@ -80,22 +136,29 @@ class TaskRunner::Impl : public QThread { if (task == nullptr) return; // TODO } + + private: + static auto generate_uuid() -> std::string { + return boost::uuids::to_string(boost::uuids::random_generator()()); + } }; -GpgFrontend::Thread::TaskRunner::TaskRunner() - : p_(SecureCreateUniqueObject()) {} +TaskRunner::TaskRunner() : p_(SecureCreateUniqueObject()) {} -GpgFrontend::Thread::TaskRunner::~TaskRunner() { +TaskRunner::~TaskRunner() { if (p_->isRunning()) { Stop(); } } -void GpgFrontend::Thread::TaskRunner::PostTask(Task* task) { - p_->PostTask(task); +void TaskRunner::PostTask(Task* task) { p_->PostTask(task); } + +void TaskRunner::PostTask(const Task::TaskRunnable& runner, + const Task::TaskCallback& cb, DataObjectPtr p_obj) { + p_->PostTask(runner, cb, p_obj); } -void GpgFrontend::Thread::TaskRunner::PostConcurrentTask(Task* task) { +void TaskRunner::PostConcurrentTask(Task* task) { p_->PostConcurrentTask(task); } -- cgit v1.2.3 From 644aa4397b03dbef73f8bfedc13925b51cad836b Mon Sep 17 00:00:00 2001 From: saturneric Date: Fri, 5 Jan 2024 20:55:15 +0800 Subject: feat: integrate logging api to core --- src/core/thread/TaskRunner.cpp | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) (limited to 'src/core/thread/TaskRunner.cpp') diff --git a/src/core/thread/TaskRunner.cpp b/src/core/thread/TaskRunner.cpp index 72266d20..0e9c9098 100644 --- a/src/core/thread/TaskRunner.cpp +++ b/src/core/thread/TaskRunner.cpp @@ -44,15 +44,15 @@ class TaskRunner::Impl : public QThread { void PostTask(Task* task) { if (task == nullptr) { - SPDLOG_ERROR("task posted is null"); + GF_CORE_LOG_ERROR("task posted is null"); return; } task->setParent(nullptr); task->moveToThread(this); - SPDLOG_TRACE("runner starts task: {} at thread: {}", task->GetFullID(), - this->currentThreadId()); + GF_CORE_LOG_TRACE("runner starts task: {} at thread: {}", task->GetFullID(), + this->currentThreadId()); task->SafelyRun(); } @@ -64,45 +64,48 @@ class TaskRunner::Impl : public QThread { QtConcurrent::run(runner, data_object).then([=](int rtn) { if (!cb) { - SPDLOG_TRACE("task {} doesn't have a callback function", task_uuid); + GF_CORE_LOG_TRACE("task {} doesn't have a callback function", + task_uuid); return; } if (callback_thread == QThread::currentThread()) { - SPDLOG_TRACE("for task {}, the callback thread is the same thread: {}", - task_uuid, static_cast(callback_thread)); + GF_CORE_LOG_TRACE( + "for task {}, the callback thread is the same thread: {}", + task_uuid, static_cast(callback_thread)); cb(rtn, data_object); // raise signal, announcing this task comes to an end - SPDLOG_TRACE( + GF_CORE_LOG_TRACE( "for task {}, its life comes to an end in the same thread " "after its callback executed.", task_uuid); } else { - SPDLOG_TRACE("for task {}, callback thread is a different thread: {}", - task_uuid, static_cast(callback_thread)); + GF_CORE_LOG_TRACE( + "for task {}, callback thread is a different thread: {}", task_uuid, + static_cast(callback_thread)); if (!QMetaObject::invokeMethod(callback_thread, [=]() { - SPDLOG_TRACE("calling callback of task {}", task_uuid); + GF_CORE_LOG_TRACE("calling callback of task {}", task_uuid); try { cb(rtn, data_object); } catch (...) { - SPDLOG_ERROR( + GF_CORE_LOG_ERROR( "unknown exception was caught when execute " "callback of task {}", task_uuid); } // raise signal, announcing this task comes to an end - SPDLOG_TRACE( + GF_CORE_LOG_TRACE( "for task {}, its life comes to an end whether its " "callback function fails or not.", task_uuid); })) { - SPDLOG_ERROR( + GF_CORE_LOG_ERROR( "task {} had failed to invoke the callback function to " "target thread", task_uuid); - SPDLOG_TRACE( + GF_CORE_LOG_TRACE( "for task {}, its life must come to an end now, although it " "has something not done yet.", task_uuid); @@ -113,7 +116,7 @@ class TaskRunner::Impl : public QThread { void PostConcurrentTask(Task* task) { if (task == nullptr) { - SPDLOG_ERROR("task posted is null"); + GF_CORE_LOG_ERROR("task posted is null"); return; } @@ -128,7 +131,8 @@ class TaskRunner::Impl : public QThread { concurrent_thread->start(); - SPDLOG_TRACE("runner starts task concurrenctly: {}", task->GetFullID()); + GF_CORE_LOG_TRACE("runner starts task concurrenctly: {}", + task->GetFullID()); task->SafelyRun(); } -- cgit v1.2.3 From 57438e754cd857ef48c3960eefe2e957716acd80 Mon Sep 17 00:00:00 2001 From: saturneric Date: Fri, 5 Jan 2024 21:28:59 +0800 Subject: fix: slove a multi-threads issue at task model --- src/core/thread/TaskRunner.cpp | 66 +++++------------------------------------- 1 file changed, 7 insertions(+), 59 deletions(-) (limited to 'src/core/thread/TaskRunner.cpp') diff --git a/src/core/thread/TaskRunner.cpp b/src/core/thread/TaskRunner.cpp index 0e9c9098..dbd14225 100644 --- a/src/core/thread/TaskRunner.cpp +++ b/src/core/thread/TaskRunner.cpp @@ -56,62 +56,9 @@ class TaskRunner::Impl : public QThread { task->SafelyRun(); } - static void PostTask(const Task::TaskRunnable& runner, - const Task::TaskCallback& cb, DataObjectPtr p_obj) { - auto* callback_thread = QThread::currentThread(); - auto data_object = std::move(p_obj); - const auto task_uuid = generate_uuid(); - - QtConcurrent::run(runner, data_object).then([=](int rtn) { - if (!cb) { - GF_CORE_LOG_TRACE("task {} doesn't have a callback function", - task_uuid); - return; - } - - if (callback_thread == QThread::currentThread()) { - GF_CORE_LOG_TRACE( - "for task {}, the callback thread is the same thread: {}", - task_uuid, static_cast(callback_thread)); - - cb(rtn, data_object); - - // raise signal, announcing this task comes to an end - GF_CORE_LOG_TRACE( - "for task {}, its life comes to an end in the same thread " - "after its callback executed.", - task_uuid); - } else { - GF_CORE_LOG_TRACE( - "for task {}, callback thread is a different thread: {}", task_uuid, - static_cast(callback_thread)); - if (!QMetaObject::invokeMethod(callback_thread, [=]() { - GF_CORE_LOG_TRACE("calling callback of task {}", task_uuid); - try { - cb(rtn, data_object); - } catch (...) { - GF_CORE_LOG_ERROR( - "unknown exception was caught when execute " - "callback of task {}", - task_uuid); - } - // raise signal, announcing this task comes to an end - GF_CORE_LOG_TRACE( - "for task {}, its life comes to an end whether its " - "callback function fails or not.", - task_uuid); - })) { - GF_CORE_LOG_ERROR( - "task {} had failed to invoke the callback function to " - "target thread", - task_uuid); - GF_CORE_LOG_TRACE( - "for task {}, its life must come to an end now, although it " - "has something not done yet.", - task_uuid); - } - } - }); + void PostTask(const std::string& name, const Task::TaskRunnable& runnerable, + const Task::TaskCallback& cb, DataObjectPtr params) { + PostTask(new Task(runnerable, name, std::move(params), cb)); } void PostConcurrentTask(Task* task) { @@ -157,9 +104,10 @@ TaskRunner::~TaskRunner() { void TaskRunner::PostTask(Task* task) { p_->PostTask(task); } -void TaskRunner::PostTask(const Task::TaskRunnable& runner, - const Task::TaskCallback& cb, DataObjectPtr p_obj) { - p_->PostTask(runner, cb, p_obj); +void TaskRunner::PostTask(const std::string& name, + const Task::TaskRunnable& runner, + const Task::TaskCallback& cb, DataObjectPtr params) { + p_->PostTask(name, runner, cb, std::move(params)); } void TaskRunner::PostConcurrentTask(Task* task) { -- cgit v1.2.3 From bf538056b24a68b8fd235b1c50991ee8eb46a776 Mon Sep 17 00:00:00 2001 From: saturneric Date: Fri, 12 Jan 2024 14:02:37 +0800 Subject: refactor: use QString instead of std::string and improve threading system --- src/core/thread/TaskRunner.cpp | 45 +++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 12 deletions(-) (limited to 'src/core/thread/TaskRunner.cpp') diff --git a/src/core/thread/TaskRunner.cpp b/src/core/thread/TaskRunner.cpp index dbd14225..19587e70 100644 --- a/src/core/thread/TaskRunner.cpp +++ b/src/core/thread/TaskRunner.cpp @@ -28,12 +28,6 @@ #include "core/thread/TaskRunner.h" -#include -#include -#include -#include -#include - #include "core/thread/Task.h" namespace GpgFrontend::Thread { @@ -56,7 +50,32 @@ class TaskRunner::Impl : public QThread { task->SafelyRun(); } - void PostTask(const std::string& name, const Task::TaskRunnable& runnerable, + std::tuple, Task::TaskTrigger> RegisterTask( + const QString& name, const Task::TaskRunnable& runnerable, + const Task::TaskCallback& cb, DataObjectPtr params) { + auto raw_task = SecureCreateQSharedObject(runnerable, name, + std::move(params), cb); + raw_task->setParent(nullptr); + raw_task->moveToThread(this); + + connect(raw_task.get(), &Task::SignalRun, this, [this, raw_task]() { + pending_tasks_[raw_task->GetFullID()] = raw_task; + }); + + connect(raw_task.get(), &Task::SignalTaskEnd, this, [this, raw_task]() { + pending_tasks_.remove(raw_task->GetFullID()); + }); + + GF_CORE_LOG_TRACE("runner starts task: {} at thread: {}", + raw_task->GetFullID(), this->currentThreadId()); + + QPointer const task = raw_task.get(); + return {nullptr, [task]() { + if (task != nullptr) task->SafelyRun(); + }}; + } + + void PostTask(const QString& name, const Task::TaskRunnable& runnerable, const Task::TaskCallback& cb, DataObjectPtr params) { PostTask(new Task(runnerable, name, std::move(params), cb)); } @@ -89,9 +108,7 @@ class TaskRunner::Impl : public QThread { } private: - static auto generate_uuid() -> std::string { - return boost::uuids::to_string(boost::uuids::random_generator()()); - } + QMap> pending_tasks_; }; TaskRunner::TaskRunner() : p_(SecureCreateUniqueObject()) {} @@ -104,8 +121,7 @@ TaskRunner::~TaskRunner() { void TaskRunner::PostTask(Task* task) { p_->PostTask(task); } -void TaskRunner::PostTask(const std::string& name, - const Task::TaskRunnable& runner, +void TaskRunner::PostTask(const QString& name, const Task::TaskRunnable& runner, const Task::TaskCallback& cb, DataObjectPtr params) { p_->PostTask(name, runner, cb, std::move(params)); } @@ -129,4 +145,9 @@ auto TaskRunner::GetThread() -> QThread* { return p_.get(); } auto TaskRunner::IsRunning() -> bool { return p_->isRunning(); } +std::tuple, Task::TaskTrigger> TaskRunner::RegisterTask( + const QString& name, const Task::TaskRunnable& runnable, + const Task::TaskCallback& cb, DataObjectPtr p_pbj) { + return p_->RegisterTask(name, runnable, cb, p_pbj); +} } // namespace GpgFrontend::Thread -- cgit v1.2.3 From 5adbd09fcb24f829ee110a5d387269aee13c558c Mon Sep 17 00:00:00 2001 From: saturneric Date: Tue, 16 Jan 2024 02:01:59 +0800 Subject: feat: upgrade threading system and make it clearer --- src/core/thread/TaskRunner.cpp | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'src/core/thread/TaskRunner.cpp') diff --git a/src/core/thread/TaskRunner.cpp b/src/core/thread/TaskRunner.cpp index 19587e70..8e381384 100644 --- a/src/core/thread/TaskRunner.cpp +++ b/src/core/thread/TaskRunner.cpp @@ -50,29 +50,25 @@ class TaskRunner::Impl : public QThread { task->SafelyRun(); } - std::tuple, Task::TaskTrigger> RegisterTask( - const QString& name, const Task::TaskRunnable& runnerable, - const Task::TaskCallback& cb, DataObjectPtr params) { - auto raw_task = SecureCreateQSharedObject(runnerable, name, - std::move(params), cb); + auto RegisterTask(const QString& name, const Task::TaskRunnable& runnerable, + const Task::TaskCallback& cb, DataObjectPtr params) + -> Task::TaskHandler { + auto* raw_task = new Task(runnerable, name, std::move(params), cb); raw_task->setParent(nullptr); raw_task->moveToThread(this); - connect(raw_task.get(), &Task::SignalRun, this, [this, raw_task]() { + connect(raw_task, &Task::SignalRun, this, [this, raw_task]() { pending_tasks_[raw_task->GetFullID()] = raw_task; }); - connect(raw_task.get(), &Task::SignalTaskEnd, this, [this, raw_task]() { + connect(raw_task, &Task::SignalTaskEnd, this, [this, raw_task]() { pending_tasks_.remove(raw_task->GetFullID()); }); GF_CORE_LOG_TRACE("runner starts task: {} at thread: {}", raw_task->GetFullID(), this->currentThreadId()); - QPointer const task = raw_task.get(); - return {nullptr, [task]() { - if (task != nullptr) task->SafelyRun(); - }}; + return Task::TaskHandler(raw_task); } void PostTask(const QString& name, const Task::TaskRunnable& runnerable, @@ -108,7 +104,7 @@ class TaskRunner::Impl : public QThread { } private: - QMap> pending_tasks_; + QMap pending_tasks_; }; TaskRunner::TaskRunner() : p_(SecureCreateUniqueObject()) {} @@ -145,9 +141,10 @@ auto TaskRunner::GetThread() -> QThread* { return p_.get(); } auto TaskRunner::IsRunning() -> bool { return p_->isRunning(); } -std::tuple, Task::TaskTrigger> TaskRunner::RegisterTask( - const QString& name, const Task::TaskRunnable& runnable, - const Task::TaskCallback& cb, DataObjectPtr p_pbj) { +auto TaskRunner::RegisterTask(const QString& name, + const Task::TaskRunnable& runnable, + const Task::TaskCallback& cb, DataObjectPtr p_pbj) + -> Task::TaskHandler { return p_->RegisterTask(name, runnable, cb, p_pbj); } } // namespace GpgFrontend::Thread -- cgit v1.2.3