From c1a5fff98cab4adf04210ba8120459b8e87a8fa3 Mon Sep 17 00:00:00 2001 From: saturneric Date: Sun, 15 Oct 2023 16:17:28 +0800 Subject: fix: solve some issues on linux .desktop file --- src/core/thread/Task.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/core/thread/Task.cpp') diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp index 7173b69e..a11d23d3 100644 --- a/src/core/thread/Task.cpp +++ b/src/core/thread/Task.cpp @@ -90,10 +90,8 @@ std::string GpgFrontend::Thread::Task::GetUUID() const { return uuid_; } bool GpgFrontend::Thread::Task::GetSequency() const { return sequency_; } -void GpgFrontend::Thread::Task::SetFinishAfterRun( - bool run_callback_after_runnable_finished) { - this->run_callback_after_runnable_finished_ = - run_callback_after_runnable_finished; +void GpgFrontend::Thread::Task::HoldOnLifeCycle(bool hold_on) { + this->run_callback_after_runnable_finished_ = !hold_on; } void GpgFrontend::Thread::Task::SetRTN(int rtn) { this->rtn_ = rtn; } -- cgit v1.2.3 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/Task.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/core/thread/Task.cpp') diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp index a11d23d3..c508531d 100644 --- a/src/core/thread/Task.cpp +++ b/src/core/thread/Task.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 5175b3ae6687839afa2cdfe01f2fd70d714024ed Mon Sep 17 00:00:00 2001 From: saturneric Date: Tue, 17 Oct 2023 04:19:26 +0800 Subject: refactor: use c++17 features and piml tech to rewrite DataObject and Task --- src/core/thread/Task.cpp | 228 ++++++++--------------------------------------- 1 file changed, 37 insertions(+), 191 deletions(-) (limited to 'src/core/thread/Task.cpp') diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp index c508531d..cc6a38b8 100644 --- a/src/core/thread/Task.cpp +++ b/src/core/thread/Task.cpp @@ -28,200 +28,46 @@ #include "core/thread/Task.h" -#include -#include -#include -#include -#include -#include - -#include "core/thread/TaskRunner.h" - -const std::string GpgFrontend::Thread::Task::DEFAULT_TASK_NAME = "default-task"; - -GpgFrontend::Thread::Task::Task(std::string name) - : uuid_(generate_uuid()), name_(name) { - SPDLOG_TRACE("task {}/ created", GetFullID()); - init(); -} - -GpgFrontend::Thread::Task::Task(TaskRunnable runnable, std::string name, - DataObjectPtr data_object, bool sequency) - : uuid_(generate_uuid()), - name_(name), - runnable_(std::move(runnable)), - callback_(std::move([](int, const std::shared_ptr &) {})), - callback_thread_(QThread::currentThread()), - data_object_(data_object), - sequency_(sequency) { - SPDLOG_TRACE("task {} created with runnable, callback_thread_: {}", - GetFullID(), static_cast(callback_thread_)); - init(); -} - -GpgFrontend::Thread::Task::Task(TaskRunnable runnable, std::string name, - DataObjectPtr data_object, - TaskCallback callback, bool sequency) - : uuid_(generate_uuid()), - name_(name), - runnable_(std::move(runnable)), - callback_(std::move(callback)), - callback_thread_(QThread::currentThread()), - data_object_(data_object), - sequency_(sequency) { - init(); - SPDLOG_TRACE( - "task {} created with runnable and callback, callback_thread_: {}", - GetFullID(), static_cast(callback_thread_)); -} - -GpgFrontend::Thread::Task::~Task() { - SPDLOG_TRACE("task {} destroyed", GetFullID()); -} +#include + +#include "TaskImpl.hpp" + +namespace GpgFrontend::Thread { + +const std::string DEFAULT_TASK_NAME = "unnamed-task"; + +Task::Task(std::string name) : p_(std::make_unique(this, name)) {} + +Task::Task(TaskRunnable runnable, std::string name, DataObjectPtr data_object, + bool sequency) + : p_(std::make_unique(this, runnable, name, data_object, sequency)) {} + +Task::Task(TaskRunnable runnable, std::string name, DataObjectPtr data_object, + TaskCallback callback, bool sequency) + : p_(std::make_unique(this, runnable, name, data_object, callback, + sequency)) {} + +Task::~Task() = default; /** * @brief * * @return std::string */ -std::string GpgFrontend::Thread::Task::GetFullID() const { - return uuid_ + "/" + name_; -} - -std::string GpgFrontend::Thread::Task::GetUUID() const { return uuid_; } - -bool GpgFrontend::Thread::Task::GetSequency() const { return sequency_; } - -void GpgFrontend::Thread::Task::HoldOnLifeCycle(bool hold_on) { - this->run_callback_after_runnable_finished_ = !hold_on; -} - -void GpgFrontend::Thread::Task::SetRTN(int rtn) { this->rtn_ = rtn; } - -void GpgFrontend::Thread::Task::init() { - // after runnable finished, running callback - connect(this, &Task::SignalTaskRunnableEnd, this, - &Task::slot_task_run_callback); -} - -void GpgFrontend::Thread::Task::slot_task_run_callback(int rtn) { - SPDLOG_TRACE("task runnable {} finished, rtn: {}", GetFullID(), rtn); - // set return value - this->SetRTN(rtn); - - try { - if (callback_) { - if (callback_thread_ == QThread::currentThread()) { - SPDLOG_DEBUG("callback thread is the same thread"); - if (!QMetaObject::invokeMethod(callback_thread_, - [callback = callback_, rtn = rtn_, - data_object = data_object_, this]() { - callback(rtn, data_object); - // do cleaning work - emit SignalTaskEnd(); - })) { - SPDLOG_ERROR("failed to invoke callback"); - } - // just finished, let callack thread to raise SignalTaskEnd - return; - } else { - // waiting for callback to finish - if (!QMetaObject::invokeMethod( - callback_thread_, - [callback = callback_, rtn = rtn_, - data_object = data_object_]() { callback(rtn, data_object); }, - Qt::BlockingQueuedConnection)) { - SPDLOG_ERROR("failed to invoke callback"); - } - } - } - } catch (std::exception &e) { - SPDLOG_ERROR("exception caught: {}", e.what()); - } catch (...) { - SPDLOG_ERROR("unknown exception caught"); - } - - // raise signal, announcing this task come to an end - SPDLOG_DEBUG("task {}, starting calling signal SignalTaskEnd", GetFullID()); - emit SignalTaskEnd(); -} - -void GpgFrontend::Thread::Task::run() { - SPDLOG_TRACE("task {} starting", GetFullID()); - - // build runnable package for running - auto runnable_package = [=, id = GetFullID()]() { - SPDLOG_DEBUG("task {} runnable start runing", id); - // Run() will set rtn by itself - Run(); - // raise signal to anounce after runnable returned - if (run_callback_after_runnable_finished_) emit SignalTaskRunnableEnd(rtn_); - }; - - if (thread() != QThread::currentThread()) { - SPDLOG_DEBUG("task running thread is not object living thread"); - // 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)) { - SPDLOG_ERROR("qt invoke method failed"); - } - } -} - -void GpgFrontend::Thread::Task::SlotRun() { run(); } - -void GpgFrontend::Thread::Task::Run() { - if (runnable_) { - SetRTN(runnable_(data_object_)); - } else { - SPDLOG_WARN("no runnable in task, do callback operation"); - } -} - -GpgFrontend::Thread::Task::DataObject::Destructor * -GpgFrontend::Thread::Task::DataObject::get_heap_ptr(size_t bytes_size) { - Destructor *dstr_ptr = new Destructor(); - dstr_ptr->p_obj = malloc(bytes_size); - return dstr_ptr; -} - -GpgFrontend::Thread::Task::DataObject::~DataObject() { - if (!data_objects_.empty()) - SPDLOG_WARN("data_objects_ is not empty", - "address:", static_cast(this)); - while (!data_objects_.empty()) { - free_heap_ptr(data_objects_.top()); - data_objects_.pop(); - } -} - -size_t GpgFrontend::Thread::Task::DataObject::GetObjectSize() { - return data_objects_.size(); -} - -void GpgFrontend::Thread::Task::DataObject::free_heap_ptr(Destructor *ptr) { - SPDLOG_TRACE("p_obj: {} data object: {}", - static_cast(ptr->p_obj), - static_cast(this)); - if (ptr->destroy != nullptr) { - ptr->destroy(ptr->p_obj); - } - free(const_cast(ptr->p_obj)); - delete ptr; -} - -std::string GpgFrontend::Thread::Task::generate_uuid() { - return boost::uuids::to_string(boost::uuids::random_generator()()); -} +std::string Task::GetFullID() const { return p_->GetFullID(); } + +std::string Task::GetUUID() const { return p_->GetUUID(); } + +bool Task::GetSequency() const { return p_->GetSequency(); } + +void Task::HoldOnLifeCycle(bool hold_on) { p_->HoldOnLifeCycle(hold_on); } + +void Task::SetRTN(int rtn) { p_->SetRTN(rtn); } + +void Task::SlotRun() { p_->SlotRun(); } + +void Task::Run() { p_->Run(); } + +void Task::run() { p_->RunnableInterfaceRun(); } + +} // namespace GpgFrontend::Thread \ No newline at end of file -- cgit v1.2.3 From cc35ceff23accb44e25dfc47dae920f578836804 Mon Sep 17 00:00:00 2001 From: saturneric Date: Tue, 17 Oct 2023 05:08:57 +0800 Subject: fix: solve compile and link issues --- src/core/thread/Task.cpp | 212 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 209 insertions(+), 3 deletions(-) (limited to 'src/core/thread/Task.cpp') diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp index cc6a38b8..1da18a86 100644 --- a/src/core/thread/Task.cpp +++ b/src/core/thread/Task.cpp @@ -28,12 +28,216 @@ #include "core/thread/Task.h" +#include +#include +#include #include -#include "TaskImpl.hpp" - namespace GpgFrontend::Thread { +class Task::Impl : public QObject { + Q_OBJECT + + public: + Impl(Task *parent, std::string name) + : parent_(parent), uuid_(generate_uuid()), name_(name) { + SPDLOG_TRACE("task {} created", GetFullID()); + init(); + } + + Impl(Task *parent, TaskRunnable runnable, std::string name, + DataObjectPtr data_object, bool sequency) + : parent_(parent), + uuid_(generate_uuid()), + name_(name), + runnable_(std::move(runnable)), + callback_(std::move([](int, const DataObjectPtr &) {})), + callback_thread_(QThread::currentThread()), + data_object_(data_object), + sequency_(sequency) { + SPDLOG_TRACE("task {} created with runnable, callback_thread_: {}", + GetFullID(), static_cast(callback_thread_)); + init(); + } + + Impl(Task *parent, TaskRunnable runnable, std::string name, + DataObjectPtr data_object, TaskCallback callback, bool sequency) + : parent_(parent), + uuid_(generate_uuid()), + name_(name), + runnable_(std::move(runnable)), + callback_(std::move(callback)), + callback_thread_(QThread::currentThread()), + data_object_(data_object), + sequency_(sequency) { + init(); + SPDLOG_TRACE( + "task {} created with runnable and callback, callback_thread_: {}", + GetFullID(), static_cast(callback_thread_)); + } + + ~Impl() { SPDLOG_TRACE("task {} destroyed", GetFullID()); } + + /** + * @brief + * + * @return std::string + */ + std::string GetFullID() const { return uuid_ + "/" + name_; } + + std::string GetUUID() const { return uuid_; } + + bool GetSequency() const { return sequency_; } + + void Run() { + if (runnable_) { + SetRTN(runnable_(data_object_)); + } else { + SPDLOG_WARN("no runnable in task, do callback operation"); + } + } + + /** + * @brief Set the Finish After Run object + * + * @param finish_after_run + */ + void HoldOnLifeCycle(bool hold_on) { + this->run_callback_after_runnable_finished_ = !hold_on; + } + + /** + * @brief + * + * @param rtn + */ + void SetRTN(int rtn) { this->rtn_ = rtn; } + + /** + * @brief + * + */ + void RunnableInterfaceRun() { + SPDLOG_TRACE("task {} starting", GetFullID()); + + // build runnable package for running + auto runnable_package = [=, id = GetFullID()]() { + SPDLOG_DEBUG("task {} runnable start runing", id); + // Run() will set rtn by itself + Run(); + // raise signal to anounce after runnable returned + if (run_callback_after_runnable_finished_) + emit parent_->SignalTaskRunnableEnd(rtn_); + }; + + if (thread() != QThread::currentThread()) { + SPDLOG_DEBUG("task running thread is not object living thread"); + // 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)) { + SPDLOG_ERROR("qt invoke method failed"); + } + } + } + + public slots: + + /** + * @brief + * + */ + void SlotRun() { RunnableInterfaceRun(); } + + private: + Task *parent_; + const std::string uuid_; + const std::string name_; + const bool sequency_ = true; ///< must run in the same thread + TaskCallback callback_; ///< + TaskRunnable runnable_; ///< + bool run_callback_after_runnable_finished_ = true; ///< + int rtn_ = 0; ///< + QThread *callback_thread_ = nullptr; ///< + DataObjectPtr data_object_ = nullptr; ///< + + void init() { + // after runnable finished, running callback + connect(parent_, &Task::SignalTaskRunnableEnd, this, + &Impl::slot_task_run_callback); + } + + /** + * @brief + * + * @return std::string + */ + std::string generate_uuid() { + return boost::uuids::to_string(boost::uuids::random_generator()()); + } + + private slots: + + /** + * @brief + * + */ + void slot_task_run_callback(int rtn) { + SPDLOG_TRACE("task runnable {} finished, rtn: {}", GetFullID(), rtn); + // set return value + this->SetRTN(rtn); + + try { + if (callback_) { + if (callback_thread_ == QThread::currentThread()) { + SPDLOG_DEBUG("callback thread is the same thread"); + if (!QMetaObject::invokeMethod(callback_thread_, + [callback = callback_, rtn = rtn_, + &data_object = data_object_, this]() { + callback(rtn, data_object); + // do cleaning work + emit parent_->SignalTaskEnd(); + })) { + SPDLOG_ERROR("failed to invoke callback"); + } + // just finished, let callack thread to raise SignalTaskEnd + return; + } else { + // waiting for callback to finish + if (!QMetaObject::invokeMethod( + callback_thread_, + [callback = callback_, rtn = rtn_, + data_object = data_object_]() { + callback(rtn, data_object); + }, + Qt::BlockingQueuedConnection)) { + SPDLOG_ERROR("failed to invoke callback"); + } + } + } + } catch (std::exception &e) { + SPDLOG_ERROR("exception caught: {}", e.what()); + } catch (...) { + SPDLOG_ERROR("unknown exception caught"); + } + + // raise signal, announcing this task come to an end + SPDLOG_DEBUG("task {}, starting calling signal SignalTaskEnd", GetFullID()); + emit parent_->SignalTaskEnd(); + } +}; + const std::string DEFAULT_TASK_NAME = "unnamed-task"; Task::Task(std::string name) : p_(std::make_unique(this, name)) {} @@ -70,4 +274,6 @@ void Task::Run() { p_->Run(); } void Task::run() { p_->RunnableInterfaceRun(); } -} // namespace GpgFrontend::Thread \ No newline at end of file +} // namespace GpgFrontend::Thread + +#include "Task.moc" \ No newline at end of file -- cgit v1.2.3 From 42163a07fa4a16c5f4501c96ceffcbc258913cd6 Mon Sep 17 00:00:00 2001 From: saturneric Date: Wed, 18 Oct 2023 02:04:34 +0800 Subject: feat: print stacktrace when exception caught --- src/core/thread/Task.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'src/core/thread/Task.cpp') diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp index 1da18a86..e2d1138b 100644 --- a/src/core/thread/Task.cpp +++ b/src/core/thread/Task.cpp @@ -28,6 +28,7 @@ #include "core/thread/Task.h" +#include #include #include #include @@ -123,8 +124,17 @@ class Task::Impl : public QObject { // build runnable package for running auto runnable_package = [=, id = GetFullID()]() { SPDLOG_DEBUG("task {} runnable start runing", id); - // Run() will set rtn by itself - Run(); + + try { + // Run() will set rtn by itself + parent_->Run(); + } catch (std::exception &e) { + SPDLOG_ERROR("exception caught at task: {}", e.what()); + SPDLOG_ERROR( + "exception stacktrace: {}", + boost::stacktrace::to_string(boost::stacktrace::stacktrace())); + } + // raise signal to anounce after runnable returned if (run_callback_after_runnable_finished_) emit parent_->SignalTaskRunnableEnd(rtn_); @@ -227,7 +237,10 @@ class Task::Impl : public QObject { } } } catch (std::exception &e) { - SPDLOG_ERROR("exception caught: {}", e.what()); + SPDLOG_ERROR("exception caught at task callback: {}", e.what()); + SPDLOG_ERROR( + "exception stacktrace: {}", + boost::stacktrace::to_string(boost::stacktrace::stacktrace())); } catch (...) { SPDLOG_ERROR("unknown exception caught"); } -- cgit v1.2.3 From 216905e2532a79101e987e936fdf8b353b2a4dab Mon Sep 17 00:00:00 2001 From: saturneric Date: Wed, 18 Oct 2023 17:49:06 +0800 Subject: fix: improve thread and module relation --- src/core/thread/Task.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/core/thread/Task.cpp') diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp index e2d1138b..8793ea2d 100644 --- a/src/core/thread/Task.cpp +++ b/src/core/thread/Task.cpp @@ -41,7 +41,7 @@ class Task::Impl : public QObject { public: Impl(Task *parent, std::string name) - : parent_(parent), uuid_(generate_uuid()), name_(name) { + : QObject(parent), parent_(parent), uuid_(generate_uuid()), name_(name) { SPDLOG_TRACE("task {} created", GetFullID()); init(); } @@ -118,11 +118,11 @@ class Task::Impl : public QObject { * @brief * */ - void RunnableInterfaceRun() { + void DoRunning() { SPDLOG_TRACE("task {} starting", GetFullID()); // build runnable package for running - auto runnable_package = [=, id = GetFullID()]() { + auto runnable_package = [this, id = GetFullID()]() { SPDLOG_DEBUG("task {} runnable start runing", id); try { @@ -168,10 +168,10 @@ class Task::Impl : public QObject { * @brief * */ - void SlotRun() { RunnableInterfaceRun(); } + void SlotRun() { DoRunning(); } private: - Task *parent_; + Task *const parent_; const std::string uuid_; const std::string name_; const bool sequency_ = true; ///< must run in the same thread @@ -285,7 +285,7 @@ void Task::SlotRun() { p_->SlotRun(); } void Task::Run() { p_->Run(); } -void Task::run() { p_->RunnableInterfaceRun(); } +void Task::run() { p_->DoRunning(); } } // namespace GpgFrontend::Thread -- 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/Task.cpp | 120 +++++++++++++++++------------------------------ 1 file changed, 44 insertions(+), 76 deletions(-) (limited to 'src/core/thread/Task.cpp') diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp index 8793ea2d..031dc4c7 100644 --- a/src/core/thread/Task.cpp +++ b/src/core/thread/Task.cpp @@ -34,6 +34,8 @@ #include #include +#include "spdlog/spdlog.h" + namespace GpgFrontend::Thread { class Task::Impl : public QObject { @@ -48,7 +50,8 @@ class Task::Impl : public QObject { Impl(Task *parent, TaskRunnable runnable, std::string name, DataObjectPtr data_object, bool sequency) - : parent_(parent), + : QObject(parent), + parent_(parent), uuid_(generate_uuid()), name_(name), runnable_(std::move(runnable)), @@ -63,7 +66,8 @@ class Task::Impl : public QObject { Impl(Task *parent, TaskRunnable runnable, std::string name, DataObjectPtr data_object, TaskCallback callback, bool sequency) - : parent_(parent), + : QObject(parent), + parent_(parent), uuid_(generate_uuid()), name_(name), runnable_(std::move(runnable)), @@ -71,10 +75,10 @@ class Task::Impl : public QObject { callback_thread_(QThread::currentThread()), data_object_(data_object), sequency_(sequency) { - init(); SPDLOG_TRACE( "task {} created with runnable and callback, callback_thread_: {}", GetFullID(), static_cast(callback_thread_)); + init(); } ~Impl() { SPDLOG_TRACE("task {} destroyed", GetFullID()); } @@ -91,6 +95,8 @@ class Task::Impl : public QObject { bool GetSequency() const { return sequency_; } void Run() { + SPDLOG_DEBUG("task {} is using default runnable and callback mode", + GetFullID()); if (runnable_) { SetRTN(runnable_(data_object_)); } else { @@ -114,62 +120,29 @@ class Task::Impl : public QObject { */ void SetRTN(int rtn) { this->rtn_ = rtn; } + private slots: + /** * @brief * */ - void DoRunning() { - SPDLOG_TRACE("task {} starting", GetFullID()); - - // build runnable package for running - auto runnable_package = [this, id = GetFullID()]() { - SPDLOG_DEBUG("task {} runnable start runing", id); - - try { - // Run() will set rtn by itself - parent_->Run(); - } catch (std::exception &e) { - SPDLOG_ERROR("exception caught at task: {}", e.what()); - SPDLOG_ERROR( - "exception stacktrace: {}", - boost::stacktrace::to_string(boost::stacktrace::stacktrace())); - } - - // raise signal to anounce after runnable returned - if (run_callback_after_runnable_finished_) - emit parent_->SignalTaskRunnableEnd(rtn_); - }; - - if (thread() != QThread::currentThread()) { - SPDLOG_DEBUG("task running thread is not object living thread"); - // 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)) { - SPDLOG_ERROR("qt invoke method failed"); - } + void slot_run() { + try { + SPDLOG_TRACE("task {} is starting...", GetFullID()); + // Run() will set rtn by itself + parent_->Run(); + SPDLOG_TRACE("task {} was end.", GetFullID()); + } catch (std::exception &e) { + SPDLOG_ERROR("exception was caught at task: {}", e.what()); + SPDLOG_ERROR( + "stacktrace of the exception: {}", + boost::stacktrace::to_string(boost::stacktrace::stacktrace())); } + // raise signal to anounce after runnable returned + if (run_callback_after_runnable_finished_) + emit parent_->SignalTaskRunnableEnd(rtn_); } - public slots: - - /** - * @brief - * - */ - void SlotRun() { DoRunning(); } - private: Task *const parent_; const std::string uuid_; @@ -183,6 +156,8 @@ class Task::Impl : public QObject { DataObjectPtr data_object_ = nullptr; ///< void init() { + connect(parent_, &Task::SignalRun, this, &Task::Impl::slot_run); + // after runnable finished, running callback connect(parent_, &Task::SignalTaskRunnableEnd, this, &Impl::slot_task_run_callback); @@ -211,42 +186,35 @@ class Task::Impl : public QObject { try { if (callback_) { if (callback_thread_ == QThread::currentThread()) { - SPDLOG_DEBUG("callback thread is the same thread"); + SPDLOG_DEBUG("for task {}, the callback thread is the same thread", + GetFullID(), callback_thread_->currentThreadId()); + callback_(rtn, data_object_); + } else { + SPDLOG_DEBUG("for task {}, callback thread is a different thread: {}", + GetFullID(), callback_thread_->currentThreadId()); if (!QMetaObject::invokeMethod(callback_thread_, [callback = callback_, rtn = rtn_, - &data_object = data_object_, this]() { + data_object = data_object_]() { callback(rtn, data_object); - // do cleaning work - emit parent_->SignalTaskEnd(); })) { - SPDLOG_ERROR("failed to invoke callback"); - } - // just finished, let callack thread to raise SignalTaskEnd - return; - } else { - // waiting for callback to finish - if (!QMetaObject::invokeMethod( - callback_thread_, - [callback = callback_, rtn = rtn_, - data_object = data_object_]() { - callback(rtn, data_object); - }, - Qt::BlockingQueuedConnection)) { - SPDLOG_ERROR("failed to invoke callback"); + SPDLOG_ERROR("task {} had failed to invoke callback", GetFullID()); } } } } catch (std::exception &e) { - SPDLOG_ERROR("exception caught at task callback: {}", e.what()); + SPDLOG_ERROR("exception was caught at task callback: {}", e.what()); SPDLOG_ERROR( - "exception stacktrace: {}", + "stacktrace of the exception: {}", boost::stacktrace::to_string(boost::stacktrace::stacktrace())); } catch (...) { - SPDLOG_ERROR("unknown exception caught"); + SPDLOG_ERROR("unknown exception was caught"); + SPDLOG_ERROR( + "stacktrace of the exception: {}", + boost::stacktrace::to_string(boost::stacktrace::stacktrace())); } // raise signal, announcing this task come to an end - SPDLOG_DEBUG("task {}, starting calling signal SignalTaskEnd", GetFullID()); + SPDLOG_DEBUG("for task {}, its life comes to an end.", GetFullID()); emit parent_->SignalTaskEnd(); } }; @@ -281,11 +249,11 @@ void Task::HoldOnLifeCycle(bool hold_on) { p_->HoldOnLifeCycle(hold_on); } void Task::SetRTN(int rtn) { p_->SetRTN(rtn); } -void Task::SlotRun() { p_->SlotRun(); } +void Task::SlotRun() { emit SignalRun(); } void Task::Run() { p_->Run(); } -void Task::run() { p_->DoRunning(); } +void Task::run() { emit SignalRun(); } } // 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/Task.cpp | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) (limited to 'src/core/thread/Task.cpp') diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp index 031dc4c7..bda64564 100644 --- a/src/core/thread/Task.cpp +++ b/src/core/thread/Task.cpp @@ -109,9 +109,7 @@ class Task::Impl : public QObject { * * @param finish_after_run */ - void HoldOnLifeCycle(bool hold_on) { - this->run_callback_after_runnable_finished_ = !hold_on; - } + void HoldOnLifeCycle(bool hold_on) { parent_->setAutoDelete(!hold_on); } /** * @brief @@ -139,28 +137,29 @@ class Task::Impl : public QObject { boost::stacktrace::to_string(boost::stacktrace::stacktrace())); } // raise signal to anounce after runnable returned - if (run_callback_after_runnable_finished_) - emit parent_->SignalTaskRunnableEnd(rtn_); + if (parent_->autoDelete()) slot_task_run_callback(rtn_); } private: Task *const parent_; const std::string uuid_; const std::string name_; - const bool sequency_ = true; ///< must run in the same thread - TaskCallback callback_; ///< - TaskRunnable runnable_; ///< - bool run_callback_after_runnable_finished_ = true; ///< - int rtn_ = 0; ///< - QThread *callback_thread_ = nullptr; ///< - DataObjectPtr data_object_ = nullptr; ///< + const bool sequency_ = true; ///< must run in the same thread + TaskCallback callback_; ///< + TaskRunnable runnable_; ///< + int rtn_ = 0; ///< + QThread *callback_thread_ = nullptr; ///< + DataObjectPtr data_object_ = nullptr; ///< void init() { connect(parent_, &Task::SignalRun, this, &Task::Impl::slot_run); - // after runnable finished, running callback - connect(parent_, &Task::SignalTaskRunnableEnd, this, + // + connect(parent_, &Task::SignalTaskShouldEnd, this, &Impl::slot_task_run_callback); + + // + connect(parent_, &Task::SignalTaskShouldEnd, parent_, &Task::deleteLater); } /** @@ -253,7 +252,7 @@ void Task::SlotRun() { emit SignalRun(); } void Task::Run() { p_->Run(); } -void Task::run() { emit SignalRun(); } +void Task::run() { this->SlotRun(); } } // namespace GpgFrontend::Thread -- 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/Task.cpp | 51 ++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 26 deletions(-) (limited to 'src/core/thread/Task.cpp') diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp index bda64564..6e545d81 100644 --- a/src/core/thread/Task.cpp +++ b/src/core/thread/Task.cpp @@ -28,6 +28,8 @@ #include "core/thread/Task.h" +#include + #include #include #include @@ -49,7 +51,7 @@ class Task::Impl : public QObject { } Impl(Task *parent, TaskRunnable runnable, std::string name, - DataObjectPtr data_object, bool sequency) + DataObjectPtr data_object) : QObject(parent), parent_(parent), uuid_(generate_uuid()), @@ -57,15 +59,14 @@ class Task::Impl : public QObject { runnable_(std::move(runnable)), callback_(std::move([](int, const DataObjectPtr &) {})), callback_thread_(QThread::currentThread()), - data_object_(data_object), - sequency_(sequency) { + data_object_(data_object) { SPDLOG_TRACE("task {} created with runnable, callback_thread_: {}", GetFullID(), static_cast(callback_thread_)); init(); } Impl(Task *parent, TaskRunnable runnable, std::string name, - DataObjectPtr data_object, TaskCallback callback, bool sequency) + DataObjectPtr data_object, TaskCallback callback) : QObject(parent), parent_(parent), uuid_(generate_uuid()), @@ -73,8 +74,7 @@ class Task::Impl : public QObject { runnable_(std::move(runnable)), callback_(std::move(callback)), callback_thread_(QThread::currentThread()), - data_object_(data_object), - sequency_(sequency) { + data_object_(data_object) { SPDLOG_TRACE( "task {} created with runnable and callback, callback_thread_: {}", GetFullID(), static_cast(callback_thread_)); @@ -92,8 +92,6 @@ class Task::Impl : public QObject { std::string GetUUID() const { return uuid_; } - bool GetSequency() const { return sequency_; } - void Run() { SPDLOG_DEBUG("task {} is using default runnable and callback mode", GetFullID()); @@ -137,14 +135,13 @@ class Task::Impl : public QObject { boost::stacktrace::to_string(boost::stacktrace::stacktrace())); } // raise signal to anounce after runnable returned - if (parent_->autoDelete()) slot_task_run_callback(rtn_); + if (parent_->autoDelete()) emit parent_->SignalTaskShouldEnd(rtn_); } private: Task *const parent_; const std::string uuid_; const std::string name_; - const bool sequency_ = true; ///< must run in the same thread TaskCallback callback_; ///< TaskRunnable runnable_; ///< int rtn_ = 0; ///< @@ -152,14 +149,18 @@ class Task::Impl : public QObject { DataObjectPtr data_object_ = nullptr; ///< void init() { + // + HoldOnLifeCycle(false); + + // connect(parent_, &Task::SignalRun, this, &Task::Impl::slot_run); // connect(parent_, &Task::SignalTaskShouldEnd, this, - &Impl::slot_task_run_callback); + &Impl::slot_task_should_end); // - connect(parent_, &Task::SignalTaskShouldEnd, parent_, &Task::deleteLater); + connect(parent_, &Task::SignalTaskEnd, parent_, &Task::deleteLater); } /** @@ -177,7 +178,7 @@ class Task::Impl : public QObject { * @brief * */ - void slot_task_run_callback(int rtn) { + void slot_task_should_end(int rtn) { SPDLOG_TRACE("task runnable {} finished, rtn: {}", GetFullID(), rtn); // set return value this->SetRTN(rtn); @@ -218,18 +219,14 @@ class Task::Impl : public QObject { } }; -const std::string DEFAULT_TASK_NAME = "unnamed-task"; - -Task::Task(std::string name) : p_(std::make_unique(this, name)) {} +Task::Task(std::string name) : p_(new Impl(this, name)) {} -Task::Task(TaskRunnable runnable, std::string name, DataObjectPtr data_object, - bool sequency) - : p_(std::make_unique(this, runnable, name, data_object, sequency)) {} +Task::Task(TaskRunnable runnable, std::string name, DataObjectPtr data_object) + : p_(new Impl(this, runnable, name, data_object)) {} Task::Task(TaskRunnable runnable, std::string name, DataObjectPtr data_object, - TaskCallback callback, bool sequency) - : p_(std::make_unique(this, runnable, name, data_object, callback, - sequency)) {} + TaskCallback callback) + : p_(new Impl(this, runnable, name, data_object, callback)) {} Task::~Task() = default; @@ -242,17 +239,19 @@ std::string Task::GetFullID() const { return p_->GetFullID(); } std::string Task::GetUUID() const { return p_->GetUUID(); } -bool Task::GetSequency() const { return p_->GetSequency(); } - void Task::HoldOnLifeCycle(bool hold_on) { p_->HoldOnLifeCycle(hold_on); } void Task::SetRTN(int rtn) { p_->SetRTN(rtn); } -void Task::SlotRun() { emit SignalRun(); } +void Task::SafelyRun() { emit SignalRun(); } void Task::Run() { p_->Run(); } -void Task::run() { this->SlotRun(); } +void Task::run() { + SPDLOG_DEBUG("interface run() of task {} was called by thread: {}", + GetFullID(), QThread::currentThread()->currentThreadId()); + this->SafelyRun(); +} } // namespace GpgFrontend::Thread -- 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/Task.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/core/thread/Task.cpp') diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp index 6e545d81..b1c8135a 100644 --- a/src/core/thread/Task.cpp +++ b/src/core/thread/Task.cpp @@ -149,6 +149,9 @@ class Task::Impl : public QObject { DataObjectPtr data_object_ = nullptr; ///< void init() { + SPDLOG_TRACE("task {} created, parent: {}, impl: {}", name_, + (void *)parent_, (void *)this); + // HoldOnLifeCycle(false); -- 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/Task.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'src/core/thread/Task.cpp') diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp index b1c8135a..ad3d3321 100644 --- a/src/core/thread/Task.cpp +++ b/src/core/thread/Task.cpp @@ -36,8 +36,6 @@ #include #include -#include "spdlog/spdlog.h" - namespace GpgFrontend::Thread { class Task::Impl : public QObject { @@ -56,8 +54,8 @@ class Task::Impl : public QObject { parent_(parent), uuid_(generate_uuid()), name_(name), - runnable_(std::move(runnable)), - callback_(std::move([](int, const DataObjectPtr &) {})), + runnable_(runnable), + callback_([](int, const DataObjectPtr &) {}), callback_thread_(QThread::currentThread()), data_object_(data_object) { SPDLOG_TRACE("task {} created with runnable, callback_thread_: {}", @@ -71,8 +69,8 @@ class Task::Impl : public QObject { parent_(parent), uuid_(generate_uuid()), name_(name), - runnable_(std::move(runnable)), - callback_(std::move(callback)), + runnable_(runnable), + callback_(callback), callback_thread_(QThread::currentThread()), data_object_(data_object) { SPDLOG_TRACE( @@ -142,8 +140,8 @@ class Task::Impl : public QObject { Task *const parent_; const std::string uuid_; const std::string name_; - TaskCallback callback_; ///< TaskRunnable runnable_; ///< + TaskCallback callback_; ///< int rtn_ = 0; ///< QThread *callback_thread_ = nullptr; ///< DataObjectPtr data_object_ = nullptr; ///< -- cgit v1.2.3 From 41c12e92031284e357bab04fe6e08b45c6dd3ba8 Mon Sep 17 00:00:00 2001 From: saturneric Date: Fri, 27 Oct 2023 21:21:03 +0800 Subject: feat: improve thread system and gathering gnupg options info to rt --- src/core/thread/Task.cpp | 67 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 57 insertions(+), 10 deletions(-) (limited to 'src/core/thread/Task.cpp') diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp index ad3d3321..0e0f63ac 100644 --- a/src/core/thread/Task.cpp +++ b/src/core/thread/Task.cpp @@ -29,6 +29,7 @@ #include "core/thread/Task.h" #include +#include #include #include @@ -36,6 +37,8 @@ #include #include +#include "spdlog/spdlog.h" + namespace GpgFrontend::Thread { class Task::Impl : public QObject { @@ -186,37 +189,81 @@ class Task::Impl : public QObject { try { if (callback_) { + SPDLOG_DEBUG("task {} has a callback function", GetFullID()); if (callback_thread_ == QThread::currentThread()) { SPDLOG_DEBUG("for task {}, the callback thread is the same thread", GetFullID(), callback_thread_->currentThreadId()); + callback_(rtn, data_object_); + + // raise signal, announcing this task comes to an end + SPDLOG_DEBUG( + "for task {}, its life comes to an end in the same thread after " + "its callback executed.", + parent_->GetFullID()); + emit parent_->SignalTaskEnd(); } else { SPDLOG_DEBUG("for task {}, callback thread is a different thread: {}", GetFullID(), callback_thread_->currentThreadId()); - if (!QMetaObject::invokeMethod(callback_thread_, - [callback = callback_, rtn = rtn_, - data_object = data_object_]() { - callback(rtn, data_object); - })) { - SPDLOG_ERROR("task {} had failed to invoke callback", GetFullID()); + if (!QMetaObject::invokeMethod( + callback_thread_, + [callback = callback_, rtn = rtn_, data_object = data_object_, + parent_ = this->parent_]() { + SPDLOG_DEBUG("calling callback of task {}", + parent_->GetFullID()); + try { + callback(rtn, data_object); + } catch (...) { + SPDLOG_ERROR( + "unknown exception was caught when execute " + "callback of task {}", + parent_->GetFullID()); + } + // raise signal, announcing this task comes to an end + SPDLOG_DEBUG( + "for task {}, its life comes to an end whether its " + "callback function fails or not.", + parent_->GetFullID()); + emit parent_->SignalTaskEnd(); + })) { + SPDLOG_ERROR( + "task {} had failed to invoke the callback function to target " + "thread", + GetFullID()); + SPDLOG_DEBUG( + "for task {}, its life must come to an end now, although it " + "has something not done yet.", + GetFullID()); + emit parent_->SignalTaskEnd(); } } + } else { + // raise signal, announcing this task comes to an end + SPDLOG_DEBUG( + "for task {}, its life comes to an end without callback " + "peacefully.", + GetFullID()); + emit parent_->SignalTaskEnd(); } } catch (std::exception &e) { SPDLOG_ERROR("exception was caught at task callback: {}", e.what()); SPDLOG_ERROR( "stacktrace of the exception: {}", boost::stacktrace::to_string(boost::stacktrace::stacktrace())); + // raise signal, announcing this task comes to an end + SPDLOG_DEBUG("for task {}, its life comes to an end at chaos.", + GetFullID()); + emit parent_->SignalTaskEnd(); } catch (...) { SPDLOG_ERROR("unknown exception was caught"); SPDLOG_ERROR( "stacktrace of the exception: {}", boost::stacktrace::to_string(boost::stacktrace::stacktrace())); + // raise signal, announcing this task comes to an end + SPDLOG_DEBUG("for task {}, its life comes to an end at unknown chaos.", + GetFullID()); + emit parent_->SignalTaskEnd(); } - - // raise signal, announcing this task come to an end - SPDLOG_DEBUG("for task {}, its life comes to an end.", GetFullID()); - emit parent_->SignalTaskEnd(); } }; -- 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/Task.cpp | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) (limited to 'src/core/thread/Task.cpp') diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp index 0e0f63ac..d7f1dab9 100644 --- a/src/core/thread/Task.cpp +++ b/src/core/thread/Task.cpp @@ -28,16 +28,11 @@ #include "core/thread/Task.h" -#include -#include - #include #include #include #include -#include - -#include "spdlog/spdlog.h" +#include namespace GpgFrontend::Thread { @@ -56,11 +51,11 @@ class Task::Impl : public QObject { : QObject(parent), parent_(parent), uuid_(generate_uuid()), - name_(name), - runnable_(runnable), + name_(std::move(name)), + runnable_(std::move(runnable)), callback_([](int, const DataObjectPtr &) {}), callback_thread_(QThread::currentThread()), - data_object_(data_object) { + data_object_(std::move(data_object)) { SPDLOG_TRACE("task {} created with runnable, callback_thread_: {}", GetFullID(), static_cast(callback_thread_)); init(); @@ -71,11 +66,11 @@ class Task::Impl : public QObject { : QObject(parent), parent_(parent), uuid_(generate_uuid()), - name_(name), - runnable_(runnable), - callback_(callback), + name_(std::move(name)), + runnable_(std::move(runnable)), + callback_(std::move(callback)), callback_thread_(QThread::currentThread()), - data_object_(data_object) { + data_object_(std::move(data_object)) { SPDLOG_TRACE( "task {} created with runnable and callback, callback_thread_: {}", GetFullID(), static_cast(callback_thread_)); -- cgit v1.2.3 From 0ec3358e4cfce7ad242e851c450292a25619221e Mon Sep 17 00:00:00 2001 From: saturneric Date: Sat, 2 Dec 2023 06:01:16 -0800 Subject: feat: add buddled qt pinentry and make it works --- src/core/thread/Task.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'src/core/thread/Task.cpp') diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp index d7f1dab9..92592bf4 100644 --- a/src/core/thread/Task.cpp +++ b/src/core/thread/Task.cpp @@ -89,7 +89,7 @@ class Task::Impl : public QObject { std::string GetUUID() const { return uuid_; } void Run() { - SPDLOG_DEBUG("task {} is using default runnable and callback mode", + SPDLOG_TRACE("task {} is using default runnable and callback mode", GetFullID()); if (runnable_) { SetRTN(runnable_(data_object_)); @@ -184,27 +184,27 @@ class Task::Impl : public QObject { try { if (callback_) { - SPDLOG_DEBUG("task {} has a callback function", GetFullID()); + SPDLOG_TRACE("task {} has a callback function", GetFullID()); if (callback_thread_ == QThread::currentThread()) { - SPDLOG_DEBUG("for task {}, the callback thread is the same thread", + SPDLOG_TRACE("for task {}, the callback thread is the same thread", GetFullID(), callback_thread_->currentThreadId()); callback_(rtn, data_object_); // raise signal, announcing this task comes to an end - SPDLOG_DEBUG( + SPDLOG_TRACE( "for task {}, its life comes to an end in the same thread after " "its callback executed.", parent_->GetFullID()); emit parent_->SignalTaskEnd(); } else { - SPDLOG_DEBUG("for task {}, callback thread is a different thread: {}", + SPDLOG_TRACE("for task {}, callback thread is a different thread: {}", GetFullID(), callback_thread_->currentThreadId()); if (!QMetaObject::invokeMethod( callback_thread_, [callback = callback_, rtn = rtn_, data_object = data_object_, parent_ = this->parent_]() { - SPDLOG_DEBUG("calling callback of task {}", + SPDLOG_TRACE("calling callback of task {}", parent_->GetFullID()); try { callback(rtn, data_object); @@ -215,7 +215,7 @@ class Task::Impl : public QObject { parent_->GetFullID()); } // raise signal, announcing this task comes to an end - SPDLOG_DEBUG( + SPDLOG_TRACE( "for task {}, its life comes to an end whether its " "callback function fails or not.", parent_->GetFullID()); @@ -225,7 +225,7 @@ class Task::Impl : public QObject { "task {} had failed to invoke the callback function to target " "thread", GetFullID()); - SPDLOG_DEBUG( + SPDLOG_TRACE( "for task {}, its life must come to an end now, although it " "has something not done yet.", GetFullID()); @@ -234,7 +234,7 @@ class Task::Impl : public QObject { } } else { // raise signal, announcing this task comes to an end - SPDLOG_DEBUG( + SPDLOG_TRACE( "for task {}, its life comes to an end without callback " "peacefully.", GetFullID()); @@ -246,7 +246,7 @@ class Task::Impl : public QObject { "stacktrace of the exception: {}", boost::stacktrace::to_string(boost::stacktrace::stacktrace())); // raise signal, announcing this task comes to an end - SPDLOG_DEBUG("for task {}, its life comes to an end at chaos.", + SPDLOG_TRACE("for task {}, its life comes to an end at chaos.", GetFullID()); emit parent_->SignalTaskEnd(); } catch (...) { @@ -255,7 +255,7 @@ class Task::Impl : public QObject { "stacktrace of the exception: {}", boost::stacktrace::to_string(boost::stacktrace::stacktrace())); // raise signal, announcing this task comes to an end - SPDLOG_DEBUG("for task {}, its life comes to an end at unknown chaos.", + SPDLOG_TRACE("for task {}, its life comes to an end at unknown chaos.", GetFullID()); emit parent_->SignalTaskEnd(); } @@ -291,7 +291,7 @@ void Task::SafelyRun() { emit SignalRun(); } void Task::Run() { p_->Run(); } void Task::run() { - SPDLOG_DEBUG("interface run() of task {} was called by thread: {}", + SPDLOG_TRACE("interface run() of task {} was called by thread: {}", GetFullID(), QThread::currentThread()->currentThreadId()); this->SafelyRun(); } -- 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/Task.cpp | 77 ++++++++++++++++++++++-------------------------- 1 file changed, 36 insertions(+), 41 deletions(-) (limited to 'src/core/thread/Task.cpp') diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp index 92592bf4..a5d718ee 100644 --- a/src/core/thread/Task.cpp +++ b/src/core/thread/Task.cpp @@ -28,28 +28,29 @@ #include "core/thread/Task.h" +#include + #include #include #include #include #include -namespace GpgFrontend::Thread { +#include "utils/MemoryUtils.h" -class Task::Impl : public QObject { - Q_OBJECT +namespace GpgFrontend::Thread { +class Task::Impl { public: Impl(Task *parent, std::string name) - : QObject(parent), parent_(parent), uuid_(generate_uuid()), name_(name) { + : parent_(parent), uuid_(generate_uuid()), name_(name) { SPDLOG_TRACE("task {} created", GetFullID()); init(); } Impl(Task *parent, TaskRunnable runnable, std::string name, DataObjectPtr data_object) - : QObject(parent), - parent_(parent), + : parent_(parent), uuid_(generate_uuid()), name_(std::move(name)), runnable_(std::move(runnable)), @@ -63,8 +64,7 @@ class Task::Impl : public QObject { Impl(Task *parent, TaskRunnable runnable, std::string name, DataObjectPtr data_object, TaskCallback callback) - : QObject(parent), - parent_(parent), + : parent_(parent), uuid_(generate_uuid()), name_(std::move(name)), runnable_(std::move(runnable)), @@ -112,28 +112,6 @@ class Task::Impl : public QObject { */ void SetRTN(int rtn) { this->rtn_ = rtn; } - private slots: - - /** - * @brief - * - */ - void slot_run() { - try { - SPDLOG_TRACE("task {} is starting...", GetFullID()); - // Run() will set rtn by itself - parent_->Run(); - SPDLOG_TRACE("task {} was end.", GetFullID()); - } catch (std::exception &e) { - SPDLOG_ERROR("exception was caught at task: {}", e.what()); - SPDLOG_ERROR( - "stacktrace of the exception: {}", - boost::stacktrace::to_string(boost::stacktrace::stacktrace())); - } - // raise signal to anounce after runnable returned - if (parent_->autoDelete()) emit parent_->SignalTaskShouldEnd(rtn_); - } - private: Task *const parent_; const std::string uuid_; @@ -152,27 +130,45 @@ class Task::Impl : public QObject { HoldOnLifeCycle(false); // - connect(parent_, &Task::SignalRun, this, &Task::Impl::slot_run); + connect(parent_, &Task::SignalRun, [=]() { inner_run(); }); // - connect(parent_, &Task::SignalTaskShouldEnd, this, - &Impl::slot_task_should_end); + connect(parent_, &Task::SignalTaskShouldEnd, + [=](int rtn) { slot_task_should_end(rtn); }); // connect(parent_, &Task::SignalTaskEnd, parent_, &Task::deleteLater); } + /** + * @brief + * + */ + void inner_run() { + try { + SPDLOG_TRACE("task {} is starting...", GetFullID()); + // Run() will set rtn by itself + parent_->Run(); + SPDLOG_TRACE("task {} was end.", GetFullID()); + } catch (std::exception &e) { + SPDLOG_ERROR("exception was caught at task: {}", e.what()); + SPDLOG_ERROR( + "stacktrace of the exception: {}", + boost::stacktrace::to_string(boost::stacktrace::stacktrace())); + } + // raise signal to anounce after runnable returned + if (parent_->autoDelete()) emit parent_->SignalTaskShouldEnd(rtn_); + } + /** * @brief * * @return std::string */ - std::string generate_uuid() { + static auto generate_uuid() -> std::string { return boost::uuids::to_string(boost::uuids::random_generator()()); } - private slots: - /** * @brief * @@ -265,11 +261,12 @@ class Task::Impl : public QObject { Task::Task(std::string name) : p_(new Impl(this, name)) {} Task::Task(TaskRunnable runnable, std::string name, DataObjectPtr data_object) - : p_(new Impl(this, runnable, name, data_object)) {} + : p_(SecureCreateUniqueObject(this, runnable, name, data_object)) {} Task::Task(TaskRunnable runnable, std::string name, DataObjectPtr data_object, TaskCallback callback) - : p_(new Impl(this, runnable, name, data_object, callback)) {} + : p_(SecureCreateUniqueObject(this, runnable, name, data_object, + callback)) {} Task::~Task() = default; @@ -296,6 +293,4 @@ void Task::run() { this->SafelyRun(); } -} // namespace GpgFrontend::Thread - -#include "Task.moc" \ No newline at end of file +} // namespace GpgFrontend::Thread \ No newline at end of file -- cgit v1.2.3 From ee1a6bba20d71e710b169269565202d26794f44e Mon Sep 17 00:00:00 2001 From: saturneric Date: Sat, 23 Dec 2023 00:34:46 +0800 Subject: fix: slove compilation issue on macos --- src/core/thread/Task.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/core/thread/Task.cpp') diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp index a5d718ee..3b27e52f 100644 --- a/src/core/thread/Task.cpp +++ b/src/core/thread/Task.cpp @@ -177,8 +177,9 @@ class Task::Impl { SPDLOG_TRACE("task runnable {} finished, rtn: {}", GetFullID(), rtn); // set return value this->SetRTN(rtn); - +#ifdef RELEASE try { +#endif if (callback_) { SPDLOG_TRACE("task {} has a callback function", GetFullID()); if (callback_thread_ == QThread::currentThread()) { @@ -236,6 +237,7 @@ class Task::Impl { GetFullID()); emit parent_->SignalTaskEnd(); } +#ifdef RELEASE } catch (std::exception &e) { SPDLOG_ERROR("exception was caught at task callback: {}", e.what()); SPDLOG_ERROR( @@ -255,6 +257,7 @@ class Task::Impl { GetFullID()); emit parent_->SignalTaskEnd(); } +#endif } }; -- 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/Task.cpp | 79 +++++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 38 deletions(-) (limited to 'src/core/thread/Task.cpp') diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp index 3b27e52f..86799b9f 100644 --- a/src/core/thread/Task.cpp +++ b/src/core/thread/Task.cpp @@ -44,7 +44,7 @@ class Task::Impl { public: Impl(Task *parent, std::string name) : parent_(parent), uuid_(generate_uuid()), name_(name) { - SPDLOG_TRACE("task {} created", GetFullID()); + GF_CORE_LOG_TRACE("task {} created", GetFullID()); init(); } @@ -57,8 +57,8 @@ class Task::Impl { callback_([](int, const DataObjectPtr &) {}), callback_thread_(QThread::currentThread()), data_object_(std::move(data_object)) { - SPDLOG_TRACE("task {} created with runnable, callback_thread_: {}", - GetFullID(), static_cast(callback_thread_)); + GF_CORE_LOG_TRACE("task {} created with runnable, callback_thread_: {}", + GetFullID(), static_cast(callback_thread_)); init(); } @@ -71,13 +71,13 @@ class Task::Impl { callback_(std::move(callback)), callback_thread_(QThread::currentThread()), data_object_(std::move(data_object)) { - SPDLOG_TRACE( + GF_CORE_LOG_TRACE( "task {} created with runnable and callback, callback_thread_: {}", GetFullID(), static_cast(callback_thread_)); init(); } - ~Impl() { SPDLOG_TRACE("task {} destroyed", GetFullID()); } + ~Impl() { GF_CORE_LOG_TRACE("task {} destroyed", GetFullID()); } /** * @brief @@ -89,12 +89,12 @@ class Task::Impl { std::string GetUUID() const { return uuid_; } void Run() { - SPDLOG_TRACE("task {} is using default runnable and callback mode", - GetFullID()); + GF_CORE_LOG_TRACE("task {} is using default runnable and callback mode", + GetFullID()); if (runnable_) { SetRTN(runnable_(data_object_)); } else { - SPDLOG_WARN("no runnable in task, do callback operation"); + GF_CORE_LOG_WARN("no runnable in task, do callback operation"); } } @@ -123,8 +123,8 @@ class Task::Impl { DataObjectPtr data_object_ = nullptr; ///< void init() { - SPDLOG_TRACE("task {} created, parent: {}, impl: {}", name_, - (void *)parent_, (void *)this); + GF_CORE_LOG_TRACE("task {} created, parent: {}, impl: {}", name_, + (void *)parent_, (void *)this); // HoldOnLifeCycle(false); @@ -146,13 +146,13 @@ class Task::Impl { */ void inner_run() { try { - SPDLOG_TRACE("task {} is starting...", GetFullID()); + GF_CORE_LOG_TRACE("task {} is starting...", GetFullID()); // Run() will set rtn by itself parent_->Run(); - SPDLOG_TRACE("task {} was end.", GetFullID()); + GF_CORE_LOG_TRACE("task {} was end.", GetFullID()); } catch (std::exception &e) { - SPDLOG_ERROR("exception was caught at task: {}", e.what()); - SPDLOG_ERROR( + GF_CORE_LOG_ERROR("exception was caught at task: {}", e.what()); + GF_CORE_LOG_ERROR( "stacktrace of the exception: {}", boost::stacktrace::to_string(boost::stacktrace::stacktrace())); } @@ -174,55 +174,57 @@ class Task::Impl { * */ void slot_task_should_end(int rtn) { - SPDLOG_TRACE("task runnable {} finished, rtn: {}", GetFullID(), rtn); + GF_CORE_LOG_TRACE("task runnable {} finished, rtn: {}", GetFullID(), rtn); // set return value this->SetRTN(rtn); #ifdef RELEASE try { #endif if (callback_) { - SPDLOG_TRACE("task {} has a callback function", GetFullID()); + GF_CORE_LOG_TRACE("task {} has a callback function", GetFullID()); if (callback_thread_ == QThread::currentThread()) { - SPDLOG_TRACE("for task {}, the callback thread is the same thread", - GetFullID(), callback_thread_->currentThreadId()); + GF_CORE_LOG_TRACE( + "for task {}, the callback thread is the same thread", + GetFullID(), callback_thread_->currentThreadId()); callback_(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.", parent_->GetFullID()); emit parent_->SignalTaskEnd(); } else { - SPDLOG_TRACE("for task {}, callback thread is a different thread: {}", - GetFullID(), callback_thread_->currentThreadId()); + GF_CORE_LOG_TRACE( + "for task {}, callback thread is a different thread: {}", + GetFullID(), callback_thread_->currentThreadId()); if (!QMetaObject::invokeMethod( callback_thread_, [callback = callback_, rtn = rtn_, data_object = data_object_, parent_ = this->parent_]() { - SPDLOG_TRACE("calling callback of task {}", - parent_->GetFullID()); + GF_CORE_LOG_TRACE("calling callback of task {}", + parent_->GetFullID()); try { callback(rtn, data_object); } catch (...) { - SPDLOG_ERROR( + GF_CORE_LOG_ERROR( "unknown exception was caught when execute " "callback of task {}", parent_->GetFullID()); } // 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.", parent_->GetFullID()); emit parent_->SignalTaskEnd(); })) { - SPDLOG_ERROR( + GF_CORE_LOG_ERROR( "task {} had failed to invoke the callback function to target " "thread", GetFullID()); - SPDLOG_TRACE( + GF_CORE_LOG_TRACE( "for task {}, its life must come to an end now, although it " "has something not done yet.", GetFullID()); @@ -231,7 +233,7 @@ class Task::Impl { } } else { // raise signal, announcing this task comes to an end - SPDLOG_TRACE( + GF_CORE_LOG_TRACE( "for task {}, its life comes to an end without callback " "peacefully.", GetFullID()); @@ -239,22 +241,23 @@ class Task::Impl { } #ifdef RELEASE } catch (std::exception &e) { - SPDLOG_ERROR("exception was caught at task callback: {}", e.what()); - SPDLOG_ERROR( + GF_CORE_LOG_ERROR("exception was caught at task callback: {}", e.what()); + GF_CORE_LOG_ERROR( "stacktrace of the exception: {}", boost::stacktrace::to_string(boost::stacktrace::stacktrace())); // raise signal, announcing this task comes to an end - SPDLOG_TRACE("for task {}, its life comes to an end at chaos.", - GetFullID()); + GF_CORE_LOG_TRACE("for task {}, its life comes to an end at chaos.", + GetFullID()); emit parent_->SignalTaskEnd(); } catch (...) { - SPDLOG_ERROR("unknown exception was caught"); - SPDLOG_ERROR( + GF_CORE_LOG_ERROR("unknown exception was caught"); + GF_CORE_LOG_ERROR( "stacktrace of the exception: {}", boost::stacktrace::to_string(boost::stacktrace::stacktrace())); // raise signal, announcing this task comes to an end - SPDLOG_TRACE("for task {}, its life comes to an end at unknown chaos.", - GetFullID()); + GF_CORE_LOG_TRACE( + "for task {}, its life comes to an end at unknown chaos.", + GetFullID()); emit parent_->SignalTaskEnd(); } #endif @@ -291,8 +294,8 @@ void Task::SafelyRun() { emit SignalRun(); } void Task::Run() { p_->Run(); } void Task::run() { - SPDLOG_TRACE("interface run() of task {} was called by thread: {}", - GetFullID(), QThread::currentThread()->currentThreadId()); + GF_CORE_LOG_TRACE("interface run() of task {} was called by thread: {}", + GetFullID(), QThread::currentThread()->currentThreadId()); this->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/Task.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/core/thread/Task.cpp') diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp index 86799b9f..848f9cfc 100644 --- a/src/core/thread/Task.cpp +++ b/src/core/thread/Task.cpp @@ -130,10 +130,10 @@ class Task::Impl { HoldOnLifeCycle(false); // - connect(parent_, &Task::SignalRun, [=]() { inner_run(); }); + connect(parent_, &Task::SignalRun, parent_, [=]() { inner_run(); }); // - connect(parent_, &Task::SignalTaskShouldEnd, + connect(parent_, &Task::SignalTaskShouldEnd, parent_, [=](int rtn) { slot_task_should_end(rtn); }); // -- 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/Task.cpp | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) (limited to 'src/core/thread/Task.cpp') diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp index 848f9cfc..459fb55a 100644 --- a/src/core/thread/Task.cpp +++ b/src/core/thread/Task.cpp @@ -42,13 +42,13 @@ namespace GpgFrontend::Thread { class Task::Impl { public: - Impl(Task *parent, std::string name) + Impl(Task *parent, QString name) : parent_(parent), uuid_(generate_uuid()), name_(name) { GF_CORE_LOG_TRACE("task {} created", GetFullID()); init(); } - Impl(Task *parent, TaskRunnable runnable, std::string name, + Impl(Task *parent, TaskRunnable runnable, QString name, DataObjectPtr data_object) : parent_(parent), uuid_(generate_uuid()), @@ -62,7 +62,7 @@ class Task::Impl { init(); } - Impl(Task *parent, TaskRunnable runnable, std::string name, + Impl(Task *parent, TaskRunnable runnable, QString name, DataObjectPtr data_object, TaskCallback callback) : parent_(parent), uuid_(generate_uuid()), @@ -82,11 +82,13 @@ class Task::Impl { /** * @brief * - * @return std::string + * @return QString */ - std::string GetFullID() const { return uuid_ + "/" + name_; } + [[nodiscard]] auto GetFullID() const -> QString { + return uuid_ + "/" + name_; + } - std::string GetUUID() const { return uuid_; } + auto GetUUID() const -> QString { return uuid_; } void Run() { GF_CORE_LOG_TRACE("task {} is using default runnable and callback mode", @@ -114,8 +116,8 @@ class Task::Impl { private: Task *const parent_; - const std::string uuid_; - const std::string name_; + const QString uuid_; + const QString name_; TaskRunnable runnable_; ///< TaskCallback callback_; ///< int rtn_ = 0; ///< @@ -163,10 +165,10 @@ class Task::Impl { /** * @brief * - * @return std::string + * @return QString */ - static auto generate_uuid() -> std::string { - return boost::uuids::to_string(boost::uuids::random_generator()()); + static auto generate_uuid() -> QString { + return QUuid::createUuid().toString(); } /** @@ -205,14 +207,18 @@ class Task::Impl { parent_ = this->parent_]() { GF_CORE_LOG_TRACE("calling callback of task {}", parent_->GetFullID()); +#ifdef RELEASE try { +#endif callback(rtn, data_object); +#ifdef RELEASE } catch (...) { GF_CORE_LOG_ERROR( "unknown exception was caught when execute " "callback of task {}", parent_->GetFullID()); } +#endif // raise signal, announcing this task comes to an end GF_CORE_LOG_TRACE( "for task {}, its life comes to an end whether its " @@ -264,12 +270,12 @@ class Task::Impl { } }; -Task::Task(std::string name) : p_(new Impl(this, name)) {} +Task::Task(QString name) : p_(new Impl(this, name)) {} -Task::Task(TaskRunnable runnable, std::string name, DataObjectPtr data_object) +Task::Task(TaskRunnable runnable, QString name, DataObjectPtr data_object) : p_(SecureCreateUniqueObject(this, runnable, name, data_object)) {} -Task::Task(TaskRunnable runnable, std::string name, DataObjectPtr data_object, +Task::Task(TaskRunnable runnable, QString name, DataObjectPtr data_object, TaskCallback callback) : p_(SecureCreateUniqueObject(this, runnable, name, data_object, callback)) {} @@ -279,11 +285,11 @@ Task::~Task() = default; /** * @brief * - * @return std::string + * @return QString */ -std::string Task::GetFullID() const { return p_->GetFullID(); } +QString Task::GetFullID() const { return p_->GetFullID(); } -std::string Task::GetUUID() const { return p_->GetUUID(); } +QString Task::GetUUID() const { return p_->GetUUID(); } void Task::HoldOnLifeCycle(bool hold_on) { p_->HoldOnLifeCycle(hold_on); } -- cgit v1.2.3 From 6983b5c1dd82d159236ebd06cf17f071cc9c1ee9 Mon Sep 17 00:00:00 2001 From: saturneric Date: Fri, 12 Jan 2024 23:08:38 +0800 Subject: refactor: remove boost and use QString instead of std::filesystem::path --- src/core/thread/Task.cpp | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'src/core/thread/Task.cpp') diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp index 459fb55a..ae6b6760 100644 --- a/src/core/thread/Task.cpp +++ b/src/core/thread/Task.cpp @@ -30,10 +30,6 @@ #include -#include -#include -#include -#include #include #include "utils/MemoryUtils.h" @@ -154,9 +150,6 @@ class Task::Impl { GF_CORE_LOG_TRACE("task {} was end.", GetFullID()); } catch (std::exception &e) { GF_CORE_LOG_ERROR("exception was caught at task: {}", e.what()); - GF_CORE_LOG_ERROR( - "stacktrace of the exception: {}", - boost::stacktrace::to_string(boost::stacktrace::stacktrace())); } // raise signal to anounce after runnable returned if (parent_->autoDelete()) emit parent_->SignalTaskShouldEnd(rtn_); @@ -248,18 +241,12 @@ class Task::Impl { #ifdef RELEASE } catch (std::exception &e) { GF_CORE_LOG_ERROR("exception was caught at task callback: {}", e.what()); - GF_CORE_LOG_ERROR( - "stacktrace of the exception: {}", - boost::stacktrace::to_string(boost::stacktrace::stacktrace())); // raise signal, announcing this task comes to an end GF_CORE_LOG_TRACE("for task {}, its life comes to an end at chaos.", GetFullID()); emit parent_->SignalTaskEnd(); } catch (...) { GF_CORE_LOG_ERROR("unknown exception was caught"); - GF_CORE_LOG_ERROR( - "stacktrace of the exception: {}", - boost::stacktrace::to_string(boost::stacktrace::stacktrace())); // raise signal, announcing this task comes to an end GF_CORE_LOG_TRACE( "for task {}, its life comes to an end at unknown chaos.", -- 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/Task.cpp | 141 +++++++++++++++-------------------------------- 1 file changed, 43 insertions(+), 98 deletions(-) (limited to 'src/core/thread/Task.cpp') diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp index ae6b6760..717086e0 100644 --- a/src/core/thread/Task.cpp +++ b/src/core/thread/Task.cpp @@ -39,7 +39,7 @@ namespace GpgFrontend::Thread { class Task::Impl { public: Impl(Task *parent, QString name) - : parent_(parent), uuid_(generate_uuid()), name_(name) { + : parent_(parent), uuid_(generate_uuid()), name_(std::move(name)) { GF_CORE_LOG_TRACE("task {} created", GetFullID()); init(); } @@ -131,8 +131,29 @@ class Task::Impl { connect(parent_, &Task::SignalRun, parent_, [=]() { inner_run(); }); // - connect(parent_, &Task::SignalTaskShouldEnd, parent_, - [=](int rtn) { slot_task_should_end(rtn); }); + connect(parent_, &Task::SignalTaskShouldEnd, QThread::currentThread(), + [this](int rtn) { +#ifdef RELEASE + try { +#endif + if (callback_) { + GF_CORE_LOG_TRACE( + "task callback {} is starting with runnerable rtn: {}", + GetFullID(), rtn); + + callback_(rtn_, data_object_); + GF_CORE_LOG_TRACE("task callback {} finished, rtn: {}", + GetFullID(), rtn); + } + +#ifdef RELEASE + } catch (...) { + GF_CORE_LOG_ERROR("task callback {} finished, rtn: {}", + GetFullID(), rtn); + } +#endif + emit parent_->SignalTaskEnd(); + }); // connect(parent_, &Task::SignalTaskEnd, parent_, &Task::deleteLater); @@ -144,15 +165,17 @@ class Task::Impl { */ void inner_run() { try { - GF_CORE_LOG_TRACE("task {} is starting...", GetFullID()); + GF_CORE_LOG_TRACE("task runnable {} is starting...", GetFullID()); // Run() will set rtn by itself parent_->Run(); - GF_CORE_LOG_TRACE("task {} was end.", GetFullID()); + GF_CORE_LOG_TRACE("task runnable {} finished, rtn: {}", GetFullID()); } catch (std::exception &e) { GF_CORE_LOG_ERROR("exception was caught at task: {}", e.what()); } // raise signal to anounce after runnable returned - if (parent_->autoDelete()) emit parent_->SignalTaskShouldEnd(rtn_); + if (parent_->autoDelete()) { + emit parent_->SignalTaskShouldEnd(rtn_); + } } /** @@ -163,98 +186,6 @@ class Task::Impl { static auto generate_uuid() -> QString { return QUuid::createUuid().toString(); } - - /** - * @brief - * - */ - void slot_task_should_end(int rtn) { - GF_CORE_LOG_TRACE("task runnable {} finished, rtn: {}", GetFullID(), rtn); - // set return value - this->SetRTN(rtn); -#ifdef RELEASE - try { -#endif - if (callback_) { - GF_CORE_LOG_TRACE("task {} has a callback function", GetFullID()); - if (callback_thread_ == QThread::currentThread()) { - GF_CORE_LOG_TRACE( - "for task {}, the callback thread is the same thread", - GetFullID(), callback_thread_->currentThreadId()); - - callback_(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.", - parent_->GetFullID()); - emit parent_->SignalTaskEnd(); - } else { - GF_CORE_LOG_TRACE( - "for task {}, callback thread is a different thread: {}", - GetFullID(), callback_thread_->currentThreadId()); - if (!QMetaObject::invokeMethod( - callback_thread_, - [callback = callback_, rtn = rtn_, data_object = data_object_, - parent_ = this->parent_]() { - GF_CORE_LOG_TRACE("calling callback of task {}", - parent_->GetFullID()); -#ifdef RELEASE - try { -#endif - callback(rtn, data_object); -#ifdef RELEASE - } catch (...) { - GF_CORE_LOG_ERROR( - "unknown exception was caught when execute " - "callback of task {}", - parent_->GetFullID()); - } -#endif - // 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.", - parent_->GetFullID()); - emit parent_->SignalTaskEnd(); - })) { - GF_CORE_LOG_ERROR( - "task {} had failed to invoke the callback function to target " - "thread", - GetFullID()); - GF_CORE_LOG_TRACE( - "for task {}, its life must come to an end now, although it " - "has something not done yet.", - GetFullID()); - emit parent_->SignalTaskEnd(); - } - } - } else { - // raise signal, announcing this task comes to an end - GF_CORE_LOG_TRACE( - "for task {}, its life comes to an end without callback " - "peacefully.", - GetFullID()); - emit parent_->SignalTaskEnd(); - } -#ifdef RELEASE - } catch (std::exception &e) { - GF_CORE_LOG_ERROR("exception was caught at task callback: {}", e.what()); - // raise signal, announcing this task comes to an end - GF_CORE_LOG_TRACE("for task {}, its life comes to an end at chaos.", - GetFullID()); - emit parent_->SignalTaskEnd(); - } catch (...) { - GF_CORE_LOG_ERROR("unknown exception was caught"); - // raise signal, announcing this task comes to an end - GF_CORE_LOG_TRACE( - "for task {}, its life comes to an end at unknown chaos.", - GetFullID()); - emit parent_->SignalTaskEnd(); - } -#endif - } }; Task::Task(QString name) : p_(new Impl(this, name)) {} @@ -292,4 +223,18 @@ void Task::run() { this->SafelyRun(); } +Task::TaskHandler::TaskHandler(Task *task) : task_(task) {} + +void Task::TaskHandler::Start() { + if (task_ != nullptr) task_->SafelyRun(); +} + +void Task::TaskHandler::Cancel() { + if (task_ != nullptr) emit task_->SignalTaskEnd(); +} + +auto Task::TaskHandler::GetTask() -> Task * { + if (task_ != nullptr) return task_; + return nullptr; +} } // namespace GpgFrontend::Thread \ No newline at end of file -- cgit v1.2.3 From 4994f4eaa1211d402b791660ad6221154a4c2405 Mon Sep 17 00:00:00 2001 From: saturneric Date: Tue, 16 Jan 2024 11:49:50 +0800 Subject: fix: make task and threading system safer --- src/core/thread/Task.cpp | 90 +++++++++++++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 39 deletions(-) (limited to 'src/core/thread/Task.cpp') diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp index 717086e0..249d898f 100644 --- a/src/core/thread/Task.cpp +++ b/src/core/thread/Task.cpp @@ -30,8 +30,6 @@ #include -#include - #include "utils/MemoryUtils.h" namespace GpgFrontend::Thread { @@ -84,16 +82,27 @@ class Task::Impl { return uuid_ + "/" + name_; } - auto GetUUID() const -> QString { return uuid_; } + /** + * @brief + * + * @return QString + */ + [[nodiscard]] auto GetUUID() const -> QString { return uuid_; } - void Run() { - GF_CORE_LOG_TRACE("task {} is using default runnable and callback mode", + /** + * @brief + * + * @return int + */ + auto Run() -> int { + GF_CORE_LOG_TRACE("task {} is in classical runnable and callback mode", GetFullID()); - if (runnable_) { - SetRTN(runnable_(data_object_)); - } else { - GF_CORE_LOG_WARN("no runnable in task, do callback operation"); - } + + if (runnable_) return runnable_(data_object_); + + GF_CORE_LOG_WARN("no runnable in task, do callback operation, task: {}", + GetFullID()); + return 0; } /** @@ -110,13 +119,20 @@ class Task::Impl { */ void SetRTN(int rtn) { this->rtn_ = rtn; } + /** + * @brief + * + * @return auto + */ + [[nodiscard]] auto GetRTN() const { return this->rtn_; } + private: Task *const parent_; const QString uuid_; const QString name_; TaskRunnable runnable_; ///< TaskCallback callback_; ///< - int rtn_ = 0; ///< + int rtn_ = -99; ///< QThread *callback_thread_ = nullptr; ///< DataObjectPtr data_object_ = nullptr; ///< @@ -128,14 +144,14 @@ class Task::Impl { HoldOnLifeCycle(false); // - connect(parent_, &Task::SignalRun, parent_, [=]() { inner_run(); }); + connect(parent_, &Task::SignalRun, parent_, &Task::slot_exception_safe_run); // connect(parent_, &Task::SignalTaskShouldEnd, QThread::currentThread(), [this](int rtn) { -#ifdef RELEASE + // set task returning code + SetRTN(rtn); try { -#endif if (callback_) { GF_CORE_LOG_TRACE( "task callback {} is starting with runnerable rtn: {}", @@ -145,13 +161,10 @@ class Task::Impl { GF_CORE_LOG_TRACE("task callback {} finished, rtn: {}", GetFullID(), rtn); } - -#ifdef RELEASE } catch (...) { - GF_CORE_LOG_ERROR("task callback {} finished, rtn: {}", + GF_CORE_LOG_ERROR("task {} callback caught exception, rtn: {}", GetFullID(), rtn); } -#endif emit parent_->SignalTaskEnd(); }); @@ -159,25 +172,6 @@ class Task::Impl { connect(parent_, &Task::SignalTaskEnd, parent_, &Task::deleteLater); } - /** - * @brief - * - */ - void inner_run() { - try { - GF_CORE_LOG_TRACE("task runnable {} is starting...", GetFullID()); - // Run() will set rtn by itself - parent_->Run(); - GF_CORE_LOG_TRACE("task runnable {} finished, rtn: {}", GetFullID()); - } catch (std::exception &e) { - GF_CORE_LOG_ERROR("exception was caught at task: {}", e.what()); - } - // raise signal to anounce after runnable returned - if (parent_->autoDelete()) { - emit parent_->SignalTaskShouldEnd(rtn_); - } - } - /** * @brief * @@ -211,11 +205,11 @@ QString Task::GetUUID() const { return p_->GetUUID(); } void Task::HoldOnLifeCycle(bool hold_on) { p_->HoldOnLifeCycle(hold_on); } -void Task::SetRTN(int rtn) { p_->SetRTN(rtn); } +void Task::setRTN(int rtn) { p_->SetRTN(rtn); } void Task::SafelyRun() { emit SignalRun(); } -void Task::Run() { p_->Run(); } +int Task::Run() { return p_->Run(); } void Task::run() { GF_CORE_LOG_TRACE("interface run() of task {} was called by thread: {}", @@ -237,4 +231,22 @@ auto Task::TaskHandler::GetTask() -> Task * { if (task_ != nullptr) return task_; return nullptr; } + +void Task::slot_exception_safe_run() noexcept { + auto rtn = p_->GetRTN(); + try { + GF_CORE_LOG_TRACE("task runnable {} is starting...", GetFullID()); + + // Run() will set rtn by itself + rtn = this->Run(); + + GF_CORE_LOG_TRACE("task runnable {} finished, rtn: {}", GetFullID()); + } catch (...) { + GF_CORE_LOG_ERROR("exception was caught at task: {}", GetFullID()); + } + + // raise signal to anounce after runnable returned + if (this->autoDelete()) emit this->SignalTaskShouldEnd(rtn); +} +auto Task::GetRTN() { return p_->GetRTN(); } } // namespace GpgFrontend::Thread \ No newline at end of file -- cgit v1.2.3 From 5bcf07c5f6a3429bc787c31d26edd796c8cad9c6 Mon Sep 17 00:00:00 2001 From: saturneric Date: Wed, 17 Jan 2024 01:41:52 +0800 Subject: fix: solve discovered issues --- src/core/thread/Task.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/core/thread/Task.cpp') diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp index 249d898f..1d251520 100644 --- a/src/core/thread/Task.cpp +++ b/src/core/thread/Task.cpp @@ -146,8 +146,11 @@ class Task::Impl { // connect(parent_, &Task::SignalRun, parent_, &Task::slot_exception_safe_run); + auto *callback_thread = callback_thread_ != nullptr + ? callback_thread_ + : QCoreApplication::instance()->thread(); // - connect(parent_, &Task::SignalTaskShouldEnd, QThread::currentThread(), + connect(parent_, &Task::SignalTaskShouldEnd, callback_thread, [this](int rtn) { // set task returning code SetRTN(rtn); -- cgit v1.2.3 From 38e4a656dbdd14cf7a6a91cda6c814b5290acd93 Mon Sep 17 00:00:00 2001 From: saturneric Date: Thu, 18 Jan 2024 13:32:25 +0800 Subject: fix: slove codacy issues --- src/core/thread/Task.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/thread/Task.cpp') diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp index 1d251520..dc0cfe94 100644 --- a/src/core/thread/Task.cpp +++ b/src/core/thread/Task.cpp @@ -138,7 +138,7 @@ class Task::Impl { void init() { GF_CORE_LOG_TRACE("task {} created, parent: {}, impl: {}", name_, - (void *)parent_, (void *)this); + static_cast(parent_), static_cast(this)); // HoldOnLifeCycle(false); -- cgit v1.2.3