aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSaturneric <[email protected]>2022-05-20 18:10:06 +0000
committerSaturneric <[email protected]>2022-05-20 18:10:06 +0000
commit7d5a4bed7fc1c78f9be897daf4f2f50fad51f828 (patch)
treecd683b43005de0cc0fdb03733a946a72e74b6447
parentfix: improve about dialog about version checking (diff)
downloadGpgFrontend-7d5a4bed7fc1c78f9be897daf4f2f50fad51f828.tar.gz
GpgFrontend-7d5a4bed7fc1c78f9be897daf4f2f50fad51f828.zip
feat: track pending tasks in task runner system
-rw-r--r--src/core/thread/Task.cpp28
-rw-r--r--src/core/thread/Task.h6
-rw-r--r--src/core/thread/TaskRunner.cpp29
-rw-r--r--src/core/thread/TaskRunner.h5
-rw-r--r--src/core/thread/TaskRunnerGetter.h1
5 files changed, 53 insertions, 16 deletions
diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp
index 1f24b42e..6b1a27a1 100644
--- a/src/core/thread/Task.cpp
+++ b/src/core/thread/Task.cpp
@@ -64,7 +64,9 @@ GpgFrontend::Thread::Task::Task(TaskRunnable runnable, TaskCallback callback,
<< "callback_thread_: " << callback_thread_;
}
-GpgFrontend::Thread::Task::~Task() = default;
+GpgFrontend::Thread::Task::~Task() {
+ LOG(TRACE) << "Task" << uuid_ << "destroyed";
+}
std::string GpgFrontend::Thread::Task::GetUUID() const { return uuid_; }
@@ -76,21 +78,27 @@ void GpgFrontend::Thread::Task::SetRTN(int rtn) { this->rtn_ = rtn; }
void GpgFrontend::Thread::Task::init() {
connect(this, &Task::SignalTaskFinished, this, &Task::before_finish_task);
- connect(this, &Task::SignalTaskFinished, this, &Task::deleteLater);
}
void GpgFrontend::Thread::Task::before_finish_task() {
LOG(TRACE) << "Task" << uuid_ << "finished";
- if (callback_) {
- bool if_invoke = QMetaObject::invokeMethod(
- callback_thread_,
- [callback = callback_, rtn = rtn_, data_object = data_object_]() {
- callback(rtn, data_object);
- });
- if (!if_invoke) {
- LOG(ERROR) << "failed to invoke callback";
+ try {
+ if (callback_) {
+ bool if_invoke = QMetaObject::invokeMethod(
+ callback_thread_,
+ [callback = callback_, rtn = rtn_, data_object = data_object_]() {
+ callback(rtn, data_object);
+ });
+ if (!if_invoke) {
+ LOG(ERROR) << "failed to invoke callback";
+ }
}
+ } catch (std::exception &e) {
+ LOG(ERROR) << "exception caught: " << e.what();
+ } catch (...) {
+ LOG(ERROR) << "unknown exception caught";
}
+ emit SignalTaskPostFinishedDone();
}
void GpgFrontend::Thread::Task::run() {
diff --git a/src/core/thread/Task.h b/src/core/thread/Task.h
index 9f6d8669..c94baea6 100644
--- a/src/core/thread/Task.h
+++ b/src/core/thread/Task.h
@@ -207,6 +207,12 @@ class GPGFRONTEND_CORE_EXPORT Task : public QObject, public QRunnable {
*/
void SignalTaskFinished();
+ /**
+ * @brief
+ *
+ */
+ void SignalTaskPostFinishedDone();
+
protected:
/**
* @brief Set the Finish After Run object
diff --git a/src/core/thread/TaskRunner.cpp b/src/core/thread/TaskRunner.cpp
index 226aec0e..7116ca71 100644
--- a/src/core/thread/TaskRunner.cpp
+++ b/src/core/thread/TaskRunner.cpp
@@ -36,12 +36,23 @@ GpgFrontend::Thread::TaskRunner::TaskRunner() = default;
GpgFrontend::Thread::TaskRunner::~TaskRunner() = default;
void GpgFrontend::Thread::TaskRunner::PostTask(Task* task) {
- LOG(TRACE) << "called"
- << "Post Task" << task->GetUUID();
+ LOG(TRACE) << "Post Task" << task->GetUUID();
if (task == nullptr) return;
task->setParent(nullptr);
task->moveToThread(this);
+
+ connect(task, &Task::SignalTaskPostFinishedDone, this, [=]() {
+ auto it = pending_tasks_.find(task->GetUUID());
+ if (it == pending_tasks_.end()) {
+ LOG(ERROR) << "Task" << task->GetUUID() << "not found in pending tasks";
+ return;
+ } else {
+ LOG(TRACE) << "Task" << task->GetUUID() << "found in pending tasks";
+ it->second->deleteLater();
+ pending_tasks_.erase(it);
+ }
+ });
{
std::lock_guard<std::mutex> lock(tasks_mutex_);
tasks.push(task);
@@ -53,17 +64,19 @@ void GpgFrontend::Thread::TaskRunner::run() {
LOG(TRACE) << "called"
<< "thread id:" << QThread::currentThreadId();
while (true) {
+ LOG(TRACE) << "TaskRunner: A new cycle start";
if (tasks.empty()) {
- LOG(TRACE) << "TaskRunner: No tasks to run.";
+ LOG(TRACE) << "TaskRunner: No tasks to run, trapping into event loop...";
exec();
} else {
- LOG(TRACE) << "TaskRunner: Queue size:" << tasks.size();
+ LOG(TRACE) << "TaskRunner: Task queue size:" << tasks.size();
Task* task = nullptr;
{
std::lock_guard<std::mutex> lock(tasks_mutex_);
task = std::move(tasks.front());
tasks.pop();
+ pending_tasks_.insert({task->GetUUID(), task});
}
if (task != nullptr) {
@@ -74,9 +87,17 @@ void GpgFrontend::Thread::TaskRunner::run() {
} catch (const std::exception& e) {
LOG(ERROR) << "TaskRunner: Exception in Task" << task->GetUUID()
<< "Exception: " << e.what();
+
+ // destroy the task, remove the task from the pending tasks
+ task->deleteLater();
+ pending_tasks_.erase(task->GetUUID());
} catch (...) {
LOG(ERROR) << "TaskRunner: Unknwon Exception in Task"
<< task->GetUUID();
+
+ // destroy the task, remove the task from the pending tasks
+ task->deleteLater();
+ pending_tasks_.erase(task->GetUUID());
}
}
}
diff --git a/src/core/thread/TaskRunner.h b/src/core/thread/TaskRunner.h
index 14eaeae7..f18efca6 100644
--- a/src/core/thread/TaskRunner.h
+++ b/src/core/thread/TaskRunner.h
@@ -67,8 +67,9 @@ class GPGFRONTEND_CORE_EXPORT TaskRunner : public QThread {
void PostTask(Task* task);
private:
- std::queue<Task*> tasks; ///< The task queue
- std::mutex tasks_mutex_; ///< The task queue mutex
+ std::queue<Task*> tasks; ///< The task queue
+ std::map<std::string, Task*> pending_tasks_; ///< The pending tasks
+ std::mutex tasks_mutex_; ///< The task queue mutex
};
} // namespace GpgFrontend::Thread
diff --git a/src/core/thread/TaskRunnerGetter.h b/src/core/thread/TaskRunnerGetter.h
index 722484b5..afbf63af 100644
--- a/src/core/thread/TaskRunnerGetter.h
+++ b/src/core/thread/TaskRunnerGetter.h
@@ -40,6 +40,7 @@ class GPGFRONTEND_CORE_EXPORT TaskRunnerGetter
kTaskRunnerType_Default,
kTaskRunnerType_GPG,
kTaskRunnerType_IO,
+ kTaskRunnerType_Network,
};
TaskRunnerGetter(int channel = SingletonFunctionObject::GetDefaultChannel());