From c7da260b9ba5090c34a2969c95bc352087d5cc94 Mon Sep 17 00:00:00 2001 From: Dmytro Bogovych Date: Mon, 1 Oct 2018 10:23:39 +0300 Subject: [PATCH] - fixes for process output reading --- src/engine/helper/HL_Process.cpp | 30 +++++++++++++++++++++++------- src/engine/helper/HL_Process.h | 4 +++- src/engine/helper/HL_Sync.cpp | 2 +- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/engine/helper/HL_Process.cpp b/src/engine/helper/HL_Process.cpp index 9d0de366..ddfe85c4 100644 --- a/src/engine/helper/HL_Process.cpp +++ b/src/engine/helper/HL_Process.cpp @@ -81,6 +81,7 @@ std::string OsProcess::execCommand(const std::string& cmd) #include #include +#include std::string OsProcess::execCommand(const std::string& cmd) { @@ -100,22 +101,35 @@ std::string OsProcess::execCommand(const std::string& cmd) return result; } -void OsProcess::asyncExecCommand(const std::string& cmdline, +#include + +std::shared_ptr OsProcess::asyncExecCommand(const std::string& cmdline, std::function callback, bool& finish_flag) { - std::thread t([cmdline, callback, &finish_flag]() + std::shared_ptr t = std::make_shared([cmdline, callback, &finish_flag]() { std::string cp = cmdline; - std::shared_ptr pipe(popen(cp.c_str(), "r"), pclose); + FILE* pipe = popen(cp.c_str(), "r"); if (!pipe) throw std::runtime_error("Failed to run."); char buffer[1024]; std::string result = ""; - while (!feof(pipe.get()) && !finish_flag) + int f = fileno(pipe); + while (!feof(pipe) && !finish_flag) { - if (fgets(buffer, 1024, pipe.get()) != nullptr) + // Wait for more data + struct pollfd pfd{ .fd = f, .events = POLLIN }; + + while (poll(&pfd, 1, 0) == 0 && !finish_flag) + ; + + // Read data + if (finish_flag) + continue; + + if (fgets(buffer, 1024, pipe) != nullptr) { if (callback) callback(buffer); @@ -123,11 +137,13 @@ void OsProcess::asyncExecCommand(const std::string& cmdline, } } + if (pipe) + pclose(pipe); + finish_flag = true; }); - while (!finish_flag) - std::this_thread::sleep_for(std::chrono::milliseconds(1)); + return t; } #endif diff --git a/src/engine/helper/HL_Process.h b/src/engine/helper/HL_Process.h index 52347aa7..dc14b5eb 100644 --- a/src/engine/helper/HL_Process.h +++ b/src/engine/helper/HL_Process.h @@ -3,12 +3,14 @@ #include #include +#include +#include class OsProcess { public: static std::string execCommand(const std::string& cmdline); - static void asyncExecCommand(const std::string& cmdline, + static std::shared_ptr asyncExecCommand(const std::string& cmdline, std::function callback, bool& finish_flag); diff --git a/src/engine/helper/HL_Sync.cpp b/src/engine/helper/HL_Sync.cpp index d40daddd..b11cbbb8 100644 --- a/src/engine/helper/HL_Sync.cpp +++ b/src/engine/helper/HL_Sync.cpp @@ -123,7 +123,7 @@ BufferQueue::Block BufferQueue::pull(std::chrono::milliseconds timeout) std::unique_lock l(mMutex); std::cv_status status = mBlockList.empty() ? std::cv_status::timeout : std::cv_status::no_timeout; - while (mBlockList.empty() && status == std::cv_status::timeout) + if (mBlockList.empty()) status = mSignal.wait_for(l, timeout); Block r;