fix: add timeout for IOHandler read

This commit is contained in:
shxyke
2023-03-28 02:02:18 +00:00
parent 24493835ce
commit 002a05fef4
8 changed files with 48 additions and 56 deletions

View File

@@ -36,29 +36,16 @@ bool asst::MinitouchController::call_and_hup_minitouch()
return false;
}
auto check_timeout = [&](const auto& start_time) -> bool {
using namespace std::chrono_literals;
return std::chrono::steady_clock::now() - start_time < 3s;
};
if (need_exit()) {
release_minitouch(true);
return false;
}
const auto start_time = std::chrono::steady_clock::now();
while (true) {
if (need_exit()) {
release_minitouch(true);
return false;
}
pipe_str = m_minitouch_handler->read(3);
if (!check_timeout(start_time)) {
Log.info("unable to find $ from pipe_str:", Logger::separator::newline, pipe_str);
release_minitouch(true);
return false;
}
if (pipe_str.find('$') != std::string::npos) {
break;
}
pipe_str += m_minitouch_handler->read();
if (pipe_str.find('$') == std::string::npos) {
release_minitouch(true);
return false;
}
Log.info("pipe str", Logger::separator::newline, pipe_str);

View File

@@ -193,10 +193,10 @@ bool asst::IOHandlerAdbLite::write(const std::string_view data)
}
}
std::string asst::IOHandlerAdbLite::read()
std::string asst::IOHandlerAdbLite::read(unsigned timeout_sec)
{
try {
return m_handle->read();
return m_handle->read(timeout_sec);
}
catch (const std::exception& e) {
Log.error("IOHandler read failed:", e.what());

View File

@@ -50,7 +50,7 @@ namespace asst
virtual ~IOHandlerAdbLite() = default;
virtual bool write(const std::string_view data) override;
virtual std::string read() override;
virtual std::string read(unsigned timeout_sec) override;
private:
std::shared_ptr<adb::io_handle> m_handle = nullptr;

View File

@@ -40,6 +40,6 @@ namespace asst
virtual ~IOHandler() = default;
virtual bool write(const std::string_view data) = 0;
virtual std::string read() = 0;
virtual std::string read(unsigned timeout_sec) = 0;
};
}

View File

@@ -260,15 +260,26 @@ bool asst::IOHandlerPosix::write(const std::string_view data)
return false;
}
std::string asst::IOHandlerPosix::read()
std::string asst::IOHandlerPosix::read(unsigned timeout_sec)
{
if (m_process < 0 || m_read_fd < 0) return NULL;
std::string ret_str;
constexpr int PipeReadBuffSize = 4096ULL;
auto check_timeout = [&](const auto& start_time) -> bool {
using namespace std::chrono_literals;
return std::chrono::steady_clock::now() - start_time < timeout_sec * 1s;
};
auto start_time = std::chrono::steady_clock::now();
while (true) {
char buf_from_child[PipeReadBuffSize];
if (!check_timeout(start_time)) {
break;
}
ssize_t ret_read = ::read(m_read_fd, buf_from_child, PipeReadBuffSize);
if (ret_read > 0) {
ret_str.insert(ret_str.end(), buf_from_child, buf_from_child + ret_read);

View File

@@ -51,7 +51,7 @@ namespace asst
virtual ~IOHandlerPosix();
virtual bool write(const std::string_view data) override;
virtual std::string read() override;
virtual std::string read(unsigned timeout_sec) override;
private:
int m_read_fd = -1;

View File

@@ -281,11 +281,6 @@ std::shared_ptr<asst::IOHandler> asst::Win32IO::interactive_shell(const std::str
constexpr int PipeReadBuffSize = 4096ULL;
constexpr int PipeWriteBuffSize = 64 * 1024ULL;
auto check_timeout = [&](const auto& start_time) -> bool {
using namespace std::chrono_literals;
return std::chrono::steady_clock::now() - start_time < 3s;
};
SECURITY_ATTRIBUTES sa_attr_inherit {
.nLength = sizeof(SECURITY_ATTRIBUTES),
.lpSecurityDescriptor = nullptr,
@@ -329,27 +324,6 @@ std::shared_ptr<asst::IOHandler> asst::Win32IO::interactive_shell(const std::str
return nullptr;
}
auto start_time = std::chrono::steady_clock::now();
auto pipe_buffer = std::make_unique<char[]>(PipeReadBuffSize);
OVERLAPPED pipeov { .hEvent = CreateEventW(nullptr, TRUE, FALSE, nullptr) };
std::ignore = ReadFile(pipe_parent_read, pipe_buffer.get(), PipeReadBuffSize, nullptr, &pipeov);
while (true) {
if (!check_timeout(start_time)) {
Log.error("minitouch start timeout");
CloseHandle(m_process_info.hProcess);
CloseHandle(m_process_info.hThread);
CloseHandle(pipe_parent_read);
CloseHandle(pipe_parent_write);
return nullptr;
}
DWORD len = 0;
if (GetOverlappedResult(pipe_parent_read, &pipeov, &len, FALSE)) {
break;
}
}
return std::make_shared<IOHandlerWin32>(pipe_parent_read, pipe_parent_write, m_process_info);
}
@@ -382,12 +356,32 @@ asst::IOHandlerWin32::~IOHandlerWin32()
}
}
std::string asst::IOHandlerWin32::read()
std::string asst::IOHandlerWin32::read(unsigned timeout_sec)
{
auto check_timeout = [&](const auto& start_time) -> bool {
using namespace std::chrono_literals;
return std::chrono::steady_clock::now() - start_time < timeout_sec * 1s;
};
auto start_time = std::chrono::steady_clock::now();
auto pipe_buffer = std::make_unique<char[]>(PipeBufferSize);
OVERLAPPED pipeov { .hEvent = CreateEventW(nullptr, TRUE, FALSE, nullptr) };
std::ignore = ReadFile(m_read, pipe_buffer.get(), PipeBufferSize, nullptr, &pipeov);
return std::string(pipe_buffer.get());
while (true) {
if (!check_timeout(start_time)) {
CancelIoEx(m_read, &pipeov);
Log.error("read timeout");
break;
}
DWORD len = 0;
if (GetOverlappedResult(m_read, &pipeov, &len, FALSE)) {
break;
}
}
return pipe_buffer.get();
}
bool asst::IOHandlerWin32::write(const std::string_view data)

View File

@@ -69,7 +69,7 @@ namespace asst
virtual ~IOHandlerWin32();
virtual bool write(const std::string_view data) override;
virtual std::string read() override;
virtual std::string read(unsigned timeout_sec) override;
private:
HANDLE m_read = INVALID_HANDLE_VALUE;