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)
|
||||
list(APPEND LIBS ${LINUX_GL_LIBS} -ldl)
|
||||
list(APPEND IMGUI_LIBS ${LINUX_GL_LIBS} -ldl)
|
||||
list(APPEND FLAGS -DUSE_EPOLL)
|
||||
if (Fontconfig_FOUND)
|
||||
list(APPEND FLAGS -DUSE_FONTCONFIG)
|
||||
list(APPEND LIBS Fontconfig::Fontconfig)
|
||||
|
|
|
@ -3,8 +3,12 @@
|
|||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <system_error>
|
||||
#ifdef USE_EPOLL
|
||||
#include <sys/epoll.h>
|
||||
#else
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
#include "log.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) {
|
||||
int fds[2];
|
||||
struct epoll_event event = {.events = EPOLLIN | EPOLLET};
|
||||
|
||||
if (pipe(fds)) {
|
||||
int errsv = errno;
|
||||
|
@ -107,6 +110,8 @@ LogcatThread::LogcatThread(const std::string* logcat_command) : _logcat_command(
|
|||
throw;
|
||||
}
|
||||
|
||||
#ifdef USE_EPOLL
|
||||
struct epoll_event event = {.events = EPOLLIN | EPOLLET};
|
||||
this->_epoll_fd = epoll_create1(EPOLL_CLOEXEC);
|
||||
if (this->_epoll_fd == -1) {
|
||||
int errsv = errno;
|
||||
|
@ -125,14 +130,17 @@ LogcatThread::LogcatThread(const std::string* logcat_command) : _logcat_command(
|
|||
this->~LogcatThread();
|
||||
throw_system_error(errsv, "epoll_ctl() for stderr");
|
||||
}
|
||||
#endif
|
||||
|
||||
this->_thread = std::thread(&LogcatThread::_run, this, this->_stop_source.get_token());
|
||||
}
|
||||
|
||||
LogcatThread::~LogcatThread() {
|
||||
#ifdef USE_EPOLL
|
||||
if (this->_epoll_fd != -1 && close(this->_epoll_fd)) {
|
||||
log(std::string("Failed to close epoll file descriptor: close(): ") + strerror(errno));
|
||||
}
|
||||
#endif
|
||||
if (this->_stdout_read_fd != -1 && close(this->_stdout_read_fd)) {
|
||||
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));
|
||||
}
|
||||
|
||||
void LogcatThread::_run_epoll_round() {
|
||||
struct epoll_event events[EPOLL_MAX_EVENTS];
|
||||
|
||||
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;
|
||||
void LogcatThread::_run_read_round() {
|
||||
auto handle_ready_fd = [&](int fd) {
|
||||
const bool is_stdout = fd == this->_stdout_read_fd;
|
||||
char* buf = is_stdout ? this->_stdout_buf : this->_stderr_buf;
|
||||
size_t* used = is_stdout ? &this->_stdout_buf_used : &this->_stderr_buf_used;
|
||||
|
||||
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) {
|
||||
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) {
|
||||
|
@ -360,7 +409,7 @@ void LogcatThread::_run(std::stop_token stoken) {
|
|||
}
|
||||
#endif
|
||||
|
||||
this->_run_epoll_round();
|
||||
this->_run_read_round();
|
||||
|
||||
if (stoken.stop_requested() && this->_logcat_pid != -1) {
|
||||
this->_run_process_round(LogcatProcessRequest::Stop);
|
||||
|
|
|
@ -38,14 +38,16 @@ private:
|
|||
void _try_log(std::string message);
|
||||
void _handle_line(char* buf, size_t length, bool is_stdout);
|
||||
void _run(std::stop_token stoken);
|
||||
void _run_epoll_round();
|
||||
void _run_read_round();
|
||||
|
||||
void _try_reap(bool stop_requested);
|
||||
bool _handle_stop_request();
|
||||
bool _handle_start_request();
|
||||
bool _run_process_round(LogcatProcessRequest request);
|
||||
|
||||
#ifdef USE_EPOLL
|
||||
int _epoll_fd = -1;
|
||||
#endif
|
||||
int _stdout_read_fd = -1;
|
||||
int _stdout_write_fd = -1;
|
||||
int _stderr_read_fd = -1;
|
||||
|
|
Loading…
Reference in New Issue