Use poll if epoll is not available
This commit is contained in:
parent
c3a277e232
commit
381e0d075a
|
@ -67,6 +67,7 @@ if (LINUX)
|
||||||
find_package(Fontconfig)
|
find_package(Fontconfig)
|
||||||
list(APPEND LIBS ${LINUX_GL_LIBS} -ldl)
|
list(APPEND LIBS ${LINUX_GL_LIBS} -ldl)
|
||||||
list(APPEND IMGUI_LIBS ${LINUX_GL_LIBS} -ldl)
|
list(APPEND IMGUI_LIBS ${LINUX_GL_LIBS} -ldl)
|
||||||
|
list(APPEND FLAGS -DUSE_EPOLL)
|
||||||
if (Fontconfig_FOUND)
|
if (Fontconfig_FOUND)
|
||||||
list(APPEND FLAGS -DUSE_FONTCONFIG)
|
list(APPEND FLAGS -DUSE_FONTCONFIG)
|
||||||
list(APPEND LIBS Fontconfig::Fontconfig)
|
list(APPEND LIBS Fontconfig::Fontconfig)
|
||||||
|
|
|
@ -3,8 +3,12 @@
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/epoll.h>
|
|
||||||
#include <system_error>
|
#include <system_error>
|
||||||
|
#ifdef USE_EPOLL
|
||||||
|
#include <sys/epoll.h>
|
||||||
|
#else
|
||||||
|
#include <poll.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
@ -77,7 +81,6 @@ static inline void handle_fd(int fd, char* buf, size_t* used,
|
||||||
|
|
||||||
LogcatThread::LogcatThread(const std::string* logcat_command) : _logcat_command(logcat_command) {
|
LogcatThread::LogcatThread(const std::string* logcat_command) : _logcat_command(logcat_command) {
|
||||||
int fds[2];
|
int fds[2];
|
||||||
struct epoll_event event = {.events = EPOLLIN | EPOLLET};
|
|
||||||
|
|
||||||
if (pipe(fds)) {
|
if (pipe(fds)) {
|
||||||
int errsv = errno;
|
int errsv = errno;
|
||||||
|
@ -107,6 +110,8 @@ LogcatThread::LogcatThread(const std::string* logcat_command) : _logcat_command(
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_EPOLL
|
||||||
|
struct epoll_event event = {.events = EPOLLIN | EPOLLET};
|
||||||
this->_epoll_fd = epoll_create1(EPOLL_CLOEXEC);
|
this->_epoll_fd = epoll_create1(EPOLL_CLOEXEC);
|
||||||
if (this->_epoll_fd == -1) {
|
if (this->_epoll_fd == -1) {
|
||||||
int errsv = errno;
|
int errsv = errno;
|
||||||
|
@ -125,14 +130,17 @@ LogcatThread::LogcatThread(const std::string* logcat_command) : _logcat_command(
|
||||||
this->~LogcatThread();
|
this->~LogcatThread();
|
||||||
throw_system_error(errsv, "epoll_ctl() for stderr");
|
throw_system_error(errsv, "epoll_ctl() for stderr");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
this->_thread = std::thread(&LogcatThread::_run, this, this->_stop_source.get_token());
|
this->_thread = std::thread(&LogcatThread::_run, this, this->_stop_source.get_token());
|
||||||
}
|
}
|
||||||
|
|
||||||
LogcatThread::~LogcatThread() {
|
LogcatThread::~LogcatThread() {
|
||||||
|
#ifdef USE_EPOLL
|
||||||
if (this->_epoll_fd != -1 && close(this->_epoll_fd)) {
|
if (this->_epoll_fd != -1 && close(this->_epoll_fd)) {
|
||||||
log(std::string("Failed to close epoll file descriptor: close(): ") + strerror(errno));
|
log(std::string("Failed to close epoll file descriptor: close(): ") + strerror(errno));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (this->_stdout_read_fd != -1 && close(this->_stdout_read_fd)) {
|
if (this->_stdout_read_fd != -1 && close(this->_stdout_read_fd)) {
|
||||||
log(std::string("Failed to close stdout read pipe: close(): ") + strerror(errno));
|
log(std::string("Failed to close stdout read pipe: close(): ") + strerror(errno));
|
||||||
}
|
}
|
||||||
|
@ -201,27 +209,68 @@ void LogcatThread::_handle_line(char* buf, size_t length, bool is_stdout) {
|
||||||
this->_try_log(std::string("Cannot parse logcat stdout: ") + std::string(buf, length));
|
this->_try_log(std::string("Cannot parse logcat stdout: ") + std::string(buf, length));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogcatThread::_run_epoll_round() {
|
void LogcatThread::_run_read_round() {
|
||||||
struct epoll_event events[EPOLL_MAX_EVENTS];
|
auto handle_ready_fd = [&](int fd) {
|
||||||
|
const bool is_stdout = fd == this->_stdout_read_fd;
|
||||||
int ready_fds = epoll_wait(this->_epoll_fd, events, EPOLL_MAX_EVENTS, 1000);
|
|
||||||
if (ready_fds == -1) {
|
|
||||||
int errsv = errno; // just in case if std::string overrides it
|
|
||||||
this->_try_log(std::string("epoll_wait(): ") + strerror(errsv));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i=0; i < ready_fds; i++) {
|
|
||||||
const bool is_stdout = events[i].data.fd == this->_stdout_read_fd;
|
|
||||||
char* buf = is_stdout ? this->_stdout_buf : this->_stderr_buf;
|
char* buf = is_stdout ? this->_stdout_buf : this->_stderr_buf;
|
||||||
size_t* used = is_stdout ? &this->_stdout_buf_used : &this->_stderr_buf_used;
|
size_t* used = is_stdout ? &this->_stdout_buf_used : &this->_stderr_buf_used;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
handle_fd(events[i].data.fd, buf, used, &LogcatThread::_handle_line, this, is_stdout);
|
handle_fd(fd, buf, used, &LogcatThread::_handle_line, this, is_stdout);
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
this->_try_log(std::string("Failed to handle std") + (is_stdout ? "out: " : "err: ") + e.what());
|
this->_try_log(std::string("Failed to handle std") + (is_stdout ? "out: " : "err: ") + e.what());
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef USE_EPOLL
|
||||||
|
struct epoll_event events[EPOLL_MAX_EVENTS];
|
||||||
|
|
||||||
|
int ready_fds = epoll_wait(this->_epoll_fd, events, EPOLL_MAX_EVENTS, 1000);
|
||||||
|
if (ready_fds == -1) {
|
||||||
|
try {
|
||||||
|
throw_system_error("epoll_wait()");
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
this->_try_log(e.what());
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0; i < ready_fds; i++) {
|
||||||
|
handle_ready_fd(events[i].data.fd);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
struct pollfd fds[2] = {
|
||||||
|
{
|
||||||
|
.fd = this->_stdout_read_fd,
|
||||||
|
.events = POLLIN | POLLPRI,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.fd = this->_stderr_read_fd,
|
||||||
|
.events = POLLIN | POLLPRI,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
int ready_fds = poll(fds, 2, 1000);
|
||||||
|
if (ready_fds < 0) {
|
||||||
|
try {
|
||||||
|
throw_system_error("poll()");
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
this->_try_log(e.what());
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else if (ready_fds == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fds[0].events & POLLIN || fds[0].events & POLLPRI) {
|
||||||
|
handle_ready_fd(fds[0].fd);
|
||||||
|
}
|
||||||
|
// ignore errors 'cause we'll keep the pipes open until thread termination
|
||||||
|
if (fds[1].events & POLLIN || fds[1].events & POLLPRI) {
|
||||||
|
handle_ready_fd(fds[1].fd);
|
||||||
|
}
|
||||||
|
// ignore errors 'cause we'll keep the pipes open until thread termination
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogcatThread::_try_reap(bool has_request) {
|
void LogcatThread::_try_reap(bool has_request) {
|
||||||
|
@ -360,7 +409,7 @@ void LogcatThread::_run(std::stop_token stoken) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
this->_run_epoll_round();
|
this->_run_read_round();
|
||||||
|
|
||||||
if (stoken.stop_requested() && this->_logcat_pid != -1) {
|
if (stoken.stop_requested() && this->_logcat_pid != -1) {
|
||||||
this->_run_process_round(LogcatProcessRequest::Stop);
|
this->_run_process_round(LogcatProcessRequest::Stop);
|
||||||
|
|
|
@ -38,14 +38,16 @@ private:
|
||||||
void _try_log(std::string message);
|
void _try_log(std::string message);
|
||||||
void _handle_line(char* buf, size_t length, bool is_stdout);
|
void _handle_line(char* buf, size_t length, bool is_stdout);
|
||||||
void _run(std::stop_token stoken);
|
void _run(std::stop_token stoken);
|
||||||
void _run_epoll_round();
|
void _run_read_round();
|
||||||
|
|
||||||
void _try_reap(bool stop_requested);
|
void _try_reap(bool stop_requested);
|
||||||
bool _handle_stop_request();
|
bool _handle_stop_request();
|
||||||
bool _handle_start_request();
|
bool _handle_start_request();
|
||||||
bool _run_process_round(LogcatProcessRequest request);
|
bool _run_process_round(LogcatProcessRequest request);
|
||||||
|
|
||||||
|
#ifdef USE_EPOLL
|
||||||
int _epoll_fd = -1;
|
int _epoll_fd = -1;
|
||||||
|
#endif
|
||||||
int _stdout_read_fd = -1;
|
int _stdout_read_fd = -1;
|
||||||
int _stdout_write_fd = -1;
|
int _stdout_write_fd = -1;
|
||||||
int _stderr_read_fd = -1;
|
int _stderr_read_fd = -1;
|
||||||
|
|
Loading…
Reference in New Issue