aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsaturneric <[email protected]>2024-01-15 18:01:59 +0000
committersaturneric <[email protected]>2024-01-15 18:01:59 +0000
commit5adbd09fcb24f829ee110a5d387269aee13c558c (patch)
treea58983c7ce002d59d512341a73fa84cdd1b7a9da
parentfix: slove the languange settings issue (diff)
downloadGpgFrontend-5adbd09fcb24f829ee110a5d387269aee13c558c.tar.gz
GpgFrontend-5adbd09fcb24f829ee110a5d387269aee13c558c.zip
feat: upgrade threading system and make it clearer
-rw-r--r--src/core/thread/Task.cpp141
-rw-r--r--src/core/thread/Task.h17
-rw-r--r--src/core/thread/TaskRunner.cpp27
-rw-r--r--src/core/thread/TaskRunner.h6
-rw-r--r--src/core/utils/AsyncUtils.cpp73
-rw-r--r--src/core/utils/AsyncUtils.h4
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