#pragma once #include #include #include "arb.h" #include "logcat_entry.h" typedef std::variant LogcatThreadItem; #define NEWLINE_BUF_SIZE 512 * 1024 enum class LogcatProcessRequest { None, Start, Stop, }; class LogcatThread { public: // https://stackoverflow.com/a/2173764 LogcatThread(const LogcatThread&) = delete; LogcatThread& operator=(const LogcatThread&) = delete; LogcatThread(const std::string* logcat_command); ~LogcatThread(); void request_stop(); void join(); AtomicRingBuffer atomic_ring_buffer; std::atomic logcat_process_request = LogcatProcessRequest::None; std::atomic_flag logcat_process_running; #ifndef NDEBUG std::atomic_flag debug_log_request; #endif private: void _put_if_not_stopped(LogcatThreadItem item); 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_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; int _stderr_write_fd = -1; char _stdout_buf[NEWLINE_BUF_SIZE]; size_t _stdout_buf_used = 0; char _stderr_buf[NEWLINE_BUF_SIZE]; size_t _stderr_buf_used = 0; pid_t _logcat_pid = -1; char _logcat_process_kill_attempts = 0; const std::string* _logcat_command; Buffer _current_buffer = Buffer::Unknown; std::stop_source _stop_source; std::thread _thread; };