diff options
author | saturneric <[email protected]> | 2024-01-15 18:01:59 +0000 |
---|---|---|
committer | saturneric <[email protected]> | 2024-01-15 18:01:59 +0000 |
commit | 5adbd09fcb24f829ee110a5d387269aee13c558c (patch) | |
tree | a58983c7ce002d59d512341a73fa84cdd1b7a9da | |
parent | fix: slove the languange settings issue (diff) | |
download | GpgFrontend-5adbd09fcb24f829ee110a5d387269aee13c558c.tar.gz GpgFrontend-5adbd09fcb24f829ee110a5d387269aee13c558c.zip |
feat: upgrade threading system and make it clearer
-rw-r--r-- | src/core/thread/Task.cpp | 141 | ||||
-rw-r--r-- | src/core/thread/Task.h | 17 | ||||
-rw-r--r-- | src/core/thread/TaskRunner.cpp | 27 | ||||
-rw-r--r-- | src/core/thread/TaskRunner.h | 6 | ||||
-rw-r--r-- | src/core/utils/AsyncUtils.cpp | 73 | ||||
-rw-r--r-- | src/core/utils/AsyncUtils.h | 4 |
6 files changed, 114 insertions, 154 deletions
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 diff --git a/src/core/thread/Task.h b/src/core/thread/Task.h index 281c37e6..4b597ed7 100644 --- a/src/core/thread/Task.h +++ b/src/core/thread/Task.h @@ -43,7 +43,20 @@ class GPGFRONTEND_CORE_EXPORT Task : public QObject, public QRunnable { using TaskRunnable = std::function<int(DataObjectPtr)>; ///< using TaskCallback = std::function<void(int, DataObjectPtr)>; ///< - using TaskTrigger = std::function<void()>; + + class TaskHandler { + public: + explicit TaskHandler(Task*); + + void Start(); + + void Cancel(); + + auto GetTask() -> Task*; + + private: + QPointer<Task> task_; + }; /** * @brief Construct a new Task object @@ -83,7 +96,7 @@ class GPGFRONTEND_CORE_EXPORT Task : public QObject, public QRunnable { signals: void SignalRun(); - void SignalTaskShouldEnd(int rtn); + void SignalTaskShouldEnd(int); void SignalTaskEnd(); 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<QPointer<Task>, Task::TaskTrigger> RegisterTask( - const QString& name, const Task::TaskRunnable& runnerable, - const Task::TaskCallback& cb, DataObjectPtr params) { - auto raw_task = SecureCreateQSharedObject<Task>(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<Task> 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<QString, QSharedPointer<Task>> pending_tasks_; + QMap<QString, Task*> pending_tasks_; }; TaskRunner::TaskRunner() : p_(SecureCreateUniqueObject<Impl>()) {} @@ -145,9 +141,10 @@ auto TaskRunner::GetThread() -> QThread* { return p_.get(); } auto TaskRunner::IsRunning() -> bool { return p_->isRunning(); } -std::tuple<QPointer<Task>, 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 diff --git a/src/core/thread/TaskRunner.h b/src/core/thread/TaskRunner.h index 91241a06..8a93ad0b 100644 --- a/src/core/thread/TaskRunner.h +++ b/src/core/thread/TaskRunner.h @@ -99,9 +99,9 @@ class GPGFRONTEND_CORE_EXPORT TaskRunner : public QObject { * * @return std::tuple<QPointer<Task>, TaskTrigger> */ - std::tuple<QPointer<Task>, Task::TaskTrigger> RegisterTask( - const QString&, const Task::TaskRunnable&, const Task::TaskCallback&, - DataObjectPtr); + auto RegisterTask(const QString&, const Task::TaskRunnable&, + const Task::TaskCallback&, DataObjectPtr) + -> Task::TaskHandler; /** * @brief diff --git a/src/core/utils/AsyncUtils.cpp b/src/core/utils/AsyncUtils.cpp index f5289b19..15979f2b 100644 --- a/src/core/utils/AsyncUtils.cpp +++ b/src/core/utils/AsyncUtils.cpp @@ -38,7 +38,7 @@ namespace GpgFrontend { auto RunGpgOperaAsync(GpgOperaRunnable runnable, GpgOperationCallback callback, const QString& operation, const QString& minial_version) - -> std::tuple<QPointer<Thread::Task>, Thread::Task::TaskTrigger> { + -> Thread::Task::TaskHandler { const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>( "core", "gpgme.ctx.gnupg_version", minial_version); GF_CORE_LOG_DEBUG("got gnupg version from rt: {}", gnupg_version); @@ -46,45 +46,50 @@ auto RunGpgOperaAsync(GpgOperaRunnable runnable, GpgOperationCallback callback, if (CompareSoftwareVersion(gnupg_version, "2.0.15") < 0) { GF_CORE_LOG_ERROR("operator not support"); callback(GPG_ERR_NOT_SUPPORTED, TransferParams()); - return {nullptr, {}}; + return Thread::Task::TaskHandler(nullptr); } - return Thread::TaskRunnerGetter::GetInstance() - .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_GPG) - ->RegisterTask( - operation, - [=](const DataObjectPtr& data_object) -> int { - auto custom_data_object = TransferParams(); - GpgError err = runnable(custom_data_object); + auto handler = + Thread::TaskRunnerGetter::GetInstance() + .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_GPG) + ->RegisterTask( + operation, + [=](const DataObjectPtr& data_object) -> int { + auto custom_data_object = TransferParams(); + GpgError err = runnable(custom_data_object); - data_object->Swap({err, custom_data_object}); - return 0; - }, - [=](int, const DataObjectPtr& data_object) { - callback(ExtractParams<GpgError>(data_object, 0), - ExtractParams<DataObjectPtr>(data_object, 1)); - }, - TransferParams()); + data_object->Swap({err, custom_data_object}); + return 0; + }, + [=](int, const DataObjectPtr& data_object) { + callback(ExtractParams<GpgError>(data_object, 0), + ExtractParams<DataObjectPtr>(data_object, 1)); + }, + TransferParams()); + handler.Start(); + return handler; } auto RunIOOperaAsync(OperaRunnable runnable, OperationCallback callback, - const QString& operation) - -> std::tuple<QPointer<Thread::Task>, Thread::Task::TaskTrigger> { - return Thread::TaskRunnerGetter::GetInstance() - .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_IO) - ->RegisterTask( - operation, - [=](const DataObjectPtr& data_object) -> int { - auto custom_data_object = TransferParams(); - GpgError err = runnable(custom_data_object); + const QString& operation) -> Thread::Task::TaskHandler { + auto handler = + Thread::TaskRunnerGetter::GetInstance() + .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_IO) + ->RegisterTask( + operation, + [=](const DataObjectPtr& data_object) -> int { + auto custom_data_object = TransferParams(); + GpgError err = runnable(custom_data_object); - data_object->Swap({err, custom_data_object}); - return 0; - }, - [=](int, const DataObjectPtr& data_object) { - callback(ExtractParams<GFError>(data_object, 0), - ExtractParams<DataObjectPtr>(data_object, 1)); - }, - TransferParams()); + data_object->Swap({err, custom_data_object}); + return 0; + }, + [=](int, const DataObjectPtr& data_object) { + callback(ExtractParams<GFError>(data_object, 0), + ExtractParams<DataObjectPtr>(data_object, 1)); + }, + TransferParams()); + handler.Start(); + return handler; } } // namespace GpgFrontend
\ No newline at end of file diff --git a/src/core/utils/AsyncUtils.h b/src/core/utils/AsyncUtils.h index 4ca94628..e587fad2 100644 --- a/src/core/utils/AsyncUtils.h +++ b/src/core/utils/AsyncUtils.h @@ -47,7 +47,7 @@ auto GPGFRONTEND_CORE_EXPORT RunGpgOperaAsync(GpgOperaRunnable runnable, GpgOperationCallback callback, const QString& operation, const QString& minial_version) - -> std::tuple<QPointer<Thread::Task>, Thread::Task::TaskTrigger>; + -> Thread::Task::TaskHandler; /** * @brief @@ -59,5 +59,5 @@ auto GPGFRONTEND_CORE_EXPORT RunGpgOperaAsync(GpgOperaRunnable runnable, auto GPGFRONTEND_CORE_EXPORT RunIOOperaAsync(OperaRunnable runnable, OperationCallback callback, const QString& operation) - -> std::tuple<QPointer<Thread::Task>, Thread::Task::TaskTrigger>; + -> Thread::Task::TaskHandler; } // namespace GpgFrontend
\ No newline at end of file |