aboutsummaryrefslogtreecommitdiffstats
path: root/src/core/function/gpg/GpgCommandExecutor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/function/gpg/GpgCommandExecutor.cpp')
-rw-r--r--src/core/function/gpg/GpgCommandExecutor.cpp246
1 files changed, 124 insertions, 122 deletions
diff --git a/src/core/function/gpg/GpgCommandExecutor.cpp b/src/core/function/gpg/GpgCommandExecutor.cpp
index fb1d647d..5cf57b27 100644
--- a/src/core/function/gpg/GpgCommandExecutor.cpp
+++ b/src/core/function/gpg/GpgCommandExecutor.cpp
@@ -28,112 +28,22 @@
#include "GpgCommandExecutor.h"
#include <boost/format.hpp>
-#include <string>
+#include <utility>
#include "GpgFunctionObject.h"
-#include "core/thread/DataObject.h"
+#include "core/model/DataObject.h"
+#include "core/module/Module.h"
+#include "core/thread/Task.h"
#include "core/thread/TaskRunnerGetter.h"
-#include "module/Module.h"
-#include "spdlog/spdlog.h"
-#include "thread/Task.h"
namespace GpgFrontend {
-GpgCommandExecutor::ExecuteContext::ExecuteContext(
- std::string cmd, std::vector<std::string> arguments,
- GpgCommandExecutorCallback callback, Module::TaskRunnerPtr task_runner,
- GpgCommandExecutorInteractor int_func)
- : cmd(cmd),
- arguments(arguments),
- cb_func(callback),
- int_func(int_func),
- task_runner(task_runner) {}
-
-GpgCommandExecutor::GpgCommandExecutor(int channel)
- : SingletonFunctionObject<GpgCommandExecutor>(channel) {}
-
-void GpgCommandExecutor::ExecuteSync(ExecuteContext context) {
- Thread::Task *task = build_task_from_exec_ctx(context);
-
- QEventLoop looper;
- QObject::connect(task, &Thread::Task::SignalTaskEnd, &looper,
- &QEventLoop::quit);
-
- Thread::TaskRunnerPtr target_task_runner = nullptr;
-
- if (context.task_runner != nullptr) {
- target_task_runner = context.task_runner;
- } else {
- target_task_runner =
- GpgFrontend::Thread::TaskRunnerGetter::GetInstance().GetTaskRunner(
- Thread::TaskRunnerGetter::kTaskRunnerType_External_Process);
- }
-
- target_task_runner->PostTask(task);
-
- // to arvoid dead lock issue we need to check if current thread is the same as
- // target thread. if it is, we can't call exec() because it will block the
- // current thread.
- if (QThread::currentThread() != target_task_runner->GetThread()) {
- // block until task finished
- // this is to keep reference vaild until task finished
- looper.exec();
- }
-}
-
-void GpgCommandExecutor::ExecuteConcurrentlyAsync(ExecuteContexts contexts) {
- for (auto &context : contexts) {
- auto &cmd = context.cmd;
- SPDLOG_INFO("gpg concurrently called cmd {}", cmd);
-
- Thread::Task *task = build_task_from_exec_ctx(context);
-
- if (context.task_runner != nullptr)
- context.task_runner->PostTask(task);
- else
- GpgFrontend::Thread::TaskRunnerGetter::GetInstance()
- .GetTaskRunner(
- Thread::TaskRunnerGetter::kTaskRunnerType_External_Process)
- ->PostTask(task);
- }
-}
-
-void GpgCommandExecutor::ExecuteConcurrentlySync(
- const ExecuteContexts contexts) {
- QEventLoop looper;
- int remainingTasks = contexts.size();
-
- for (auto &context : contexts) {
- auto &cmd = context.cmd;
- SPDLOG_INFO("gpg concurrently called cmd {}", cmd);
-
- Thread::Task *task = build_task_from_exec_ctx(context);
-
- QObject::connect(task, &Thread::Task::SignalTaskEnd, [&]() {
- --remainingTasks;
- if (remainingTasks <= 0) {
- looper.quit();
- }
- });
-
- if (context.task_runner != nullptr)
- context.task_runner->PostTask(task);
- else
- GpgFrontend::Thread::TaskRunnerGetter::GetInstance()
- .GetTaskRunner(
- Thread::TaskRunnerGetter::kTaskRunnerType_External_Process)
- ->PostTask(task);
- }
-
- looper.exec();
-}
-
-Thread::Task *GpgCommandExecutor::build_task_from_exec_ctx(
- const ExecuteContext &context) {
- auto &cmd = context.cmd;
- auto &arguments = context.arguments;
- auto &interact_function = context.int_func;
- auto &cmd_executor_callback = context.cb_func;
+auto BuildTaskFromExecCtx(const GpgCommandExecutor::ExecuteContext &context)
+ -> Thread::Task * {
+ const auto &cmd = context.cmd;
+ const auto &arguments = context.arguments;
+ const auto &interact_function = context.int_func;
+ const auto &cmd_executor_callback = context.cb_func;
const std::string joined_argument = std::accumulate(
std::begin(arguments), std::end(arguments), std::string(),
@@ -145,21 +55,20 @@ Thread::Task *GpgCommandExecutor::build_task_from_exec_ctx(
arguments.size());
Thread::Task::TaskCallback result_callback =
- [cmd, joined_argument](int rtn, Thread::DataObjectPtr data_object) {
+ [cmd, joined_argument](int /*rtn*/, const DataObjectPtr &data_object) {
SPDLOG_DEBUG(
"data object args count of cmd executor result callback: {}",
data_object->GetObjectSize());
if (!data_object->Check<int, std::string, std::string,
- GpgCommandExecutorCallback>())
+ GpgCommandExecutorCallback>()) {
throw std::runtime_error("invalid data object size");
+ }
- auto exit_code = Thread::ExtractParams<int>(data_object, 0);
- auto process_stdout =
- Thread::ExtractParams<std::string>(data_object, 1);
- auto process_stderr =
- Thread::ExtractParams<std::string>(data_object, 2);
+ auto exit_code = ExtractParams<int>(data_object, 0);
+ auto process_stdout = ExtractParams<std::string>(data_object, 1);
+ auto process_stderr = ExtractParams<std::string>(data_object, 2);
auto callback =
- Thread::ExtractParams<GpgCommandExecutorCallback>(data_object, 3);
+ ExtractParams<GpgCommandExecutorCallback>(data_object, 3);
// call callback
SPDLOG_DEBUG(
@@ -170,31 +79,38 @@ Thread::Task *GpgCommandExecutor::build_task_from_exec_ctx(
};
Thread::Task::TaskRunnable runner =
- [joined_argument](Thread::DataObjectPtr data_object) -> int {
+ [joined_argument](const DataObjectPtr &data_object) -> int {
SPDLOG_DEBUG("process runner called, data object size: {}",
data_object->GetObjectSize());
if (!data_object->Check<std::string, std::vector<std::string>,
GpgCommandExecutorInteractor,
- GpgCommandExecutorCallback>())
+ GpgCommandExecutorCallback>()) {
throw std::runtime_error("invalid data object size");
+ }
// get arguments
- auto cmd = Thread::ExtractParams<std::string>(data_object, 0);
- auto arguments =
- Thread::ExtractParams<std::vector<std::string>>(data_object, 1);
+ auto cmd = ExtractParams<std::string>(data_object, 0);
+ auto arguments = ExtractParams<std::vector<std::string>>(data_object, 1);
auto interact_func =
- Thread::ExtractParams<GpgCommandExecutorInteractor>(data_object, 2);
- auto callback =
- Thread::ExtractParams<GpgCommandExecutorCallback>(data_object, 3);
+ ExtractParams<GpgCommandExecutorInteractor>(data_object, 2);
+ auto callback = ExtractParams<GpgCommandExecutorCallback>(data_object, 3);
+ // create process
auto *cmd_process = new QProcess();
+ // move to current thread
+ //
cmd_process->moveToThread(QThread::currentThread());
+ // set process channel mode
+ // this is to make sure we can get all output from stdout and stderr
cmd_process->setProcessChannelMode(QProcess::MergedChannels);
cmd_process->setProgram(QString::fromStdString(cmd));
+
+ // set arguments
QStringList q_arguments;
- for (const auto &argument : arguments)
+ for (const auto &argument : arguments) {
q_arguments.append(QString::fromStdString(argument));
+ }
cmd_process->setArguments(q_arguments);
QObject::connect(
@@ -223,9 +139,9 @@ Thread::Task *GpgCommandExecutor::build_task_from_exec_ctx(
cmd_process->waitForFinished();
std::string process_stdout =
- cmd_process->readAllStandardOutput().toStdString(),
- process_stderr =
- cmd_process->readAllStandardError().toStdString();
+ cmd_process->readAllStandardOutput().toStdString();
+ std::string process_stderr =
+ cmd_process->readAllStandardError().toStdString();
int exit_code = cmd_process->exitCode();
SPDLOG_DEBUG(
@@ -251,9 +167,95 @@ Thread::Task *GpgCommandExecutor::build_task_from_exec_ctx(
std::move(runner),
(boost::format("GpgCommamdExecutor(%1%){%2%}") % cmd % joined_argument)
.str(),
- Thread::TransferParams(cmd, arguments, interact_function,
- cmd_executor_callback),
+ TransferParams(cmd, arguments, interact_function, cmd_executor_callback),
std::move(result_callback));
}
+GpgCommandExecutor::ExecuteContext::ExecuteContext(
+ std::string cmd, std::vector<std::string> arguments,
+ GpgCommandExecutorCallback callback, Module::TaskRunnerPtr task_runner,
+ GpgCommandExecutorInteractor int_func)
+ : cmd(std::move(cmd)),
+ arguments(std::move(arguments)),
+ cb_func(std::move(callback)),
+ int_func(std::move(int_func)),
+ task_runner(std::move(task_runner)) {}
+
+void GpgCommandExecutor::ExecuteSync(ExecuteContext context) {
+ Thread::Task *task = BuildTaskFromExecCtx(context);
+
+ QEventLoop looper;
+ QObject::connect(task, &Thread::Task::SignalTaskEnd, &looper,
+ &QEventLoop::quit);
+
+ Thread::TaskRunnerPtr target_task_runner = nullptr;
+
+ if (context.task_runner != nullptr) {
+ target_task_runner = context.task_runner;
+ } else {
+ target_task_runner =
+ GpgFrontend::Thread::TaskRunnerGetter::GetInstance().GetTaskRunner(
+ Thread::TaskRunnerGetter::kTaskRunnerType_External_Process);
+ }
+
+ target_task_runner->PostTask(task);
+
+ // to arvoid dead lock issue we need to check if current thread is the same as
+ // target thread. if it is, we can't call exec() because it will block the
+ // current thread.
+ if (QThread::currentThread() != target_task_runner->GetThread()) {
+ // block until task finished
+ // this is to keep reference vaild until task finished
+ looper.exec();
+ }
+}
+
+void GpgCommandExecutor::ExecuteConcurrentlyAsync(ExecuteContexts contexts) {
+ for (auto &context : contexts) {
+ const auto &cmd = context.cmd;
+ SPDLOG_INFO("gpg concurrently called cmd {}", cmd);
+
+ Thread::Task *task = BuildTaskFromExecCtx(context);
+
+ if (context.task_runner != nullptr) {
+ context.task_runner->PostTask(task);
+ } else {
+ GpgFrontend::Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(
+ Thread::TaskRunnerGetter::kTaskRunnerType_External_Process)
+ ->PostTask(task);
+ }
+ }
+}
+
+void GpgCommandExecutor::ExecuteConcurrentlySync(ExecuteContexts contexts) {
+ QEventLoop looper;
+ auto remaining_tasks = contexts.size();
+
+ for (auto &context : contexts) {
+ const auto &cmd = context.cmd;
+ SPDLOG_INFO("gpg concurrently called cmd {}", cmd);
+
+ Thread::Task *task = BuildTaskFromExecCtx(context);
+
+ QObject::connect(task, &Thread::Task::SignalTaskEnd, [&]() {
+ --remaining_tasks;
+ if (remaining_tasks <= 0) {
+ looper.quit();
+ }
+ });
+
+ if (context.task_runner != nullptr) {
+ context.task_runner->PostTask(task);
+ } else {
+ GpgFrontend::Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(
+ Thread::TaskRunnerGetter::kTaskRunnerType_External_Process)
+ ->PostTask(task);
+ }
+ }
+
+ looper.exec();
+}
+
} // namespace GpgFrontend \ No newline at end of file