Add inter-thread communication
This commit is contained in:
parent
277c9500f9
commit
0132b3ca1d
|
@ -0,0 +1,49 @@
|
|||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include "logcat_thread.h"
|
||||
|
||||
#define ARB_MAX_SIZE 16
|
||||
|
||||
template<typename T>
|
||||
class AtomicRingBuffer {
|
||||
public:
|
||||
T* get();
|
||||
void increment_read();
|
||||
void put_and_increment_write(T item);
|
||||
|
||||
private:
|
||||
size_t _read = 0;
|
||||
size_t _write = 0;
|
||||
std::atomic<size_t> _used = 0;
|
||||
T _items[ARB_MAX_SIZE];
|
||||
};
|
||||
|
||||
// function bodies must be in the header because https://stackoverflow.com/a/999383
|
||||
|
||||
template<typename T>
|
||||
T* AtomicRingBuffer<T>::get() {
|
||||
if (this->_used.load() == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
return &this->_items[this->_read];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void AtomicRingBuffer<T>::increment_read() {
|
||||
if (this->_used.load() == 0) {
|
||||
return;
|
||||
}
|
||||
--this->_used;
|
||||
this->_read = (this->_read + 1) % ARB_MAX_SIZE;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void AtomicRingBuffer<T>::put_and_increment_write(T item) {
|
||||
while (this->_used.load() == ARB_MAX_SIZE) {
|
||||
printf("spinlocking!!!\n");
|
||||
}
|
||||
this->_items[this->_write] = std::move(item);
|
||||
++this->_used;
|
||||
this->_write = (this->_write + 1) % ARB_MAX_SIZE;
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "log.h"
|
||||
#include "config.h"
|
||||
#include "logcat_thread.h"
|
||||
|
||||
static inline void write_config_and_update_structures(const Config& config) {
|
||||
try {
|
||||
|
@ -13,6 +14,22 @@ static inline void write_config_and_update_structures(const Config& config) {
|
|||
}
|
||||
}
|
||||
|
||||
static inline void check_for_logcat_items(LogcatThread& logcat_thread) {
|
||||
LogcatThreadItem* logcat_thread_item;
|
||||
|
||||
while ((logcat_thread_item = logcat_thread.atomic_ring_buffer.get())) {
|
||||
if (std::holds_alternative<std::string>(*logcat_thread_item)) {
|
||||
if (!log_entries.empty()) {
|
||||
log_entries += '\n';
|
||||
}
|
||||
log_entries += std::move(std::get<std::string>(*logcat_thread_item));
|
||||
} else {
|
||||
throw std::runtime_error("Cannot handle all possible logcat thread item variants");
|
||||
}
|
||||
logcat_thread.atomic_ring_buffer.increment_read();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline void settings_window(Config& config, float* config_write_timer, bool* show_settings_window) {
|
||||
if (!ImGui::Begin("Settings", show_settings_window)) {
|
||||
|
@ -132,11 +149,13 @@ static inline void debug_window() {
|
|||
ImGui::End();
|
||||
}
|
||||
|
||||
void event_loop(ImFont* monospace_font, Config& config, float* config_write_timer, bool* run_event_loop) {
|
||||
void event_loop(ImFont* monospace_font, Config& config, float* config_write_timer, LogcatThread& logcat_thread, bool* run_event_loop) {
|
||||
static bool show_settings_window = false;
|
||||
static bool show_logs_window = false;
|
||||
static size_t log_entries_read = 0;
|
||||
|
||||
check_for_logcat_items(logcat_thread);
|
||||
|
||||
debug_window();
|
||||
|
||||
if (show_settings_window) {
|
||||
|
|
|
@ -3,5 +3,6 @@
|
|||
#include <imgui.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "logcat_thread.h"
|
||||
|
||||
void event_loop(ImFont* monospace_font, Config& config, float* config_write_timer, bool* run_event_loop);
|
||||
void event_loop(ImFont* monospace_font, Config& config, float* config_write_timer, LogcatThread& logcat_thread, bool* run_event_loop);
|
||||
|
|
|
@ -106,9 +106,12 @@ void LogcatThread::_run(std::stop_token stoken) {
|
|||
|
||||
while (!stoken.stop_requested()) {
|
||||
printf("(boop)\n");
|
||||
|
||||
int ready_fds = epoll_wait(this->_epoll_fd, events, EPOLL_MAX_EVENTS, 1000);
|
||||
if (ready_fds == -1) {
|
||||
printf("%s\n", format_log(std::string("epoll_wait(): ") + strerror(errno)).c_str());
|
||||
std::string log_entry = format_log(std::string("epoll_wait(): ") + strerror(errno));
|
||||
printf("%s\n", log_entry.c_str());
|
||||
this->atomic_ring_buffer.put_and_increment_write(std::move(log_entry));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <thread>
|
||||
#include <variant>
|
||||
#include "arb.h"
|
||||
|
||||
typedef std::variant<std::string> LogcatThreadItem;
|
||||
|
||||
class LogcatThread {
|
||||
public:
|
||||
|
@ -13,6 +17,8 @@ public:
|
|||
void request_stop();
|
||||
void join();
|
||||
|
||||
AtomicRingBuffer<LogcatThreadItem> atomic_ring_buffer;
|
||||
|
||||
private:
|
||||
void _run(std::stop_token stoken);
|
||||
|
||||
|
|
2
main.cpp
2
main.cpp
|
@ -161,7 +161,7 @@ int main(int, char**) {
|
|||
ImGui_ImplSDL2_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
event_loop(monospace_font, config, &config_write_timer, &run_event_loop);
|
||||
event_loop(monospace_font, config, &config_write_timer, logcat_thread, &run_event_loop);
|
||||
|
||||
// Rendering
|
||||
ImGui::Render();
|
||||
|
|
Loading…
Reference in New Issue