diff options
author | Saturneric <[email protected]> | 2022-05-20 18:10:06 +0000 |
---|---|---|
committer | Saturneric <[email protected]> | 2022-05-20 18:10:06 +0000 |
commit | 7d5a4bed7fc1c78f9be897daf4f2f50fad51f828 (patch) | |
tree | cd683b43005de0cc0fdb03733a946a72e74b6447 | |
parent | fix: improve about dialog about version checking (diff) | |
download | GpgFrontend-7d5a4bed7fc1c78f9be897daf4f2f50fad51f828.tar.gz GpgFrontend-7d5a4bed7fc1c78f9be897daf4f2f50fad51f828.zip |
feat: track pending tasks in task runner system
-rw-r--r-- | src/core/thread/Task.cpp | 28 | ||||
-rw-r--r-- | src/core/thread/Task.h | 6 | ||||
-rw-r--r-- | src/core/thread/TaskRunner.cpp | 29 | ||||
-rw-r--r-- | src/core/thread/TaskRunner.h | 5 | ||||
-rw-r--r-- | src/core/thread/TaskRunnerGetter.h | 1 |
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()); |