This commit is contained in:
Twaik Yont 2021-10-10 00:46:40 +03:00
parent f7f7c858fe
commit 5a07a2fadb
5 changed files with 136 additions and 158 deletions

View File

@ -14,6 +14,7 @@
#include <sys/socket.h>
#include <dirent.h>
#pragma ide diagnostic ignored "hicpp-signed-bitwise"
#define unused __attribute__((__unused__))
#define DEFAULT_WIDTH 480
@ -29,11 +30,12 @@ public:
void get_default_proportions(int32_t* width, int32_t* height) override;
void get_keymap(int *fd, int *size) override;
void window_change_callback(EGLNativeWindowType win, uint32_t width, uint32_t height, uint32_t physical_width, uint32_t physical_height);
void layout_change_callback(char *layout);
void layout_change_callback(const char *layout);
void passfd(int fd);
void on_egl_init();
void on_egl_uninit();
void unused on_egl_uninit();
LorieEGLHelper helper;
@ -47,13 +49,11 @@ public:
LorieBackendAndroid::LorieBackendAndroid()
: self(&LorieCompositor::start, this) {}
void LorieBackendAndroid::on_egl_init() {
renderer.init();
}
void LorieBackendAndroid::on_egl_uninit() {
void unused LorieBackendAndroid::on_egl_uninit() {
renderer.uninit();
}
@ -62,8 +62,8 @@ void LorieBackendAndroid::backend_init() {
LOGE("Failed to initialize EGL context");
}
helper.onInit = std::bind(std::mem_fn(&LorieBackendAndroid::on_egl_init), this);
//helper.onUninit = std::bind(std::mem_fn(&LorieBackendAndroid::on_egl_uninit), this);
helper.onInit = [this](){ on_egl_init(); };
//helper.onUninit = [this](){ on_egl_uninit(); };
if (xkb_context == nullptr) {
xkb_context = xkb_context_new((enum xkb_context_flags) 0);
@ -145,15 +145,17 @@ void LorieBackendAndroid::get_keymap(int *fd, int *size) {
void LorieBackendAndroid::window_change_callback(EGLNativeWindowType win, uint32_t width, uint32_t height, uint32_t physical_width, uint32_t physical_height) {
LOGE("WindowChangeCallback");
helper.setWindow(win);
output_resize(width, height, physical_width, physical_height);
post([this, width, height, physical_width, physical_height]() {
output_resize(width, height, physical_width, physical_height);
});
}
void LorieBackendAndroid::layout_change_callback(char *layout) {
void LorieBackendAndroid::layout_change_callback(const char *layout) {
xkb_keymap_unref(xkb_keymap);
xkb_names.layout = layout;
xkb_keymap = xkb_keymap_new_from_names(xkb_context, &xkb_names, (xkb_keymap_compile_flags)0);
if (xkb_keymap == NULL) {
if (xkb_keymap == nullptr) {
LOGE("failed to compile global XKB keymap\n");
LOGE(" tried rules %s, model %s, layout %s, variant %s, "
"options %s\n",
@ -163,11 +165,13 @@ void LorieBackendAndroid::layout_change_callback(char *layout) {
return;
}
keyboard_keymap_changed();
post([this]() {
keyboard_keymap_changed();
});
}
void LorieBackendAndroid::passfd(int fd) {
listen(fd, 128);
wl_display_add_socket_fd(display, fd);
wl_display_add_socket_fd(display, fd);
}
///////////////////////////////////////////////////////////
@ -190,28 +194,30 @@ static LorieBackendAndroid* fromLong(jlong v) {
extern "C" JNIEXPORT jlong JNICALL
JNI_DECLARE(LorieService, createLorieThread)(unused JNIEnv *env, unused jobject instance) {
return (jlong) new LorieBackendAndroid;
return (jlong) new LorieBackendAndroid;
}
extern "C" JNIEXPORT void JNICALL
JNI_DECLARE(LorieService, passWaylandFD)(unused JNIEnv *env, unused jobject instance, jlong jcompositor, jint fd) {
if (jcompositor == 0) return;
LorieBackendAndroid *b = fromLong(jcompositor);
char path[256] = {0};
char realpath[256] = {0};
sprintf(path, "/proc/self/fd/%d", fd);
readlink(path, realpath, sizeof(realpath));
if (jcompositor == 0) return;
LorieBackendAndroid *b = fromLong(jcompositor);
char path[256] = {0};
char realpath[256] = {0};
sprintf(path, "/proc/self/fd/%d", fd);
readlink(path, realpath, sizeof(realpath));
LOGI("JNI: got fd %d (%s)", fd, realpath);
b->passfd(fd);
b->passfd(fd);
}
extern "C" JNIEXPORT void JNICALL
JNI_DECLARE(LorieService, terminate)(unused JNIEnv *env, unused jobject instance, jlong jcompositor) {
if (jcompositor == 0) return;
LorieBackendAndroid *b = fromLong(jcompositor);
LOGI("JNI: requested termination");
b->terminate();
if (jcompositor == 0) return;
LorieBackendAndroid *b = fromLong(jcompositor);
LOGI("JNI: requested termination");
b->post([b](){
b->terminate();
});
b->self.join();
}
@ -221,7 +227,9 @@ JNI_DECLARE(LorieService, windowChanged)(JNIEnv *env, unused jobject instance, j
LorieBackendAndroid *b = fromLong(jcompositor);
EGLNativeWindowType win = ANativeWindow_fromSurface(env, jsurface);
b->queue.call(&LorieBackendAndroid::window_change_callback, b, win, width, height, mmWidth, mmHeight);
b->post([b, win, width, height, mmWidth, mmHeight](){
b->window_change_callback(win, width, height, mmWidth, mmHeight);
});
LOGV("JNI: window is changed: %p(%p) %dx%d (%dmm x %dmm)", win, jsurface, width, height, mmWidth, mmHeight);
}
@ -232,7 +240,9 @@ JNI_DECLARE(LorieService, touchDown)(unused JNIEnv *env, unused jobject instance
LorieBackendAndroid *b = fromLong(jcompositor);
LOGV("JNI: touch down");
b->touch_down(static_cast<uint32_t>(id), static_cast<uint32_t>(x), static_cast<uint32_t>(y));
b->post([b, id, x, y]() {
b->touch_down(static_cast<uint32_t>(id), static_cast<uint32_t>(x), static_cast<uint32_t>(y));
});
}
extern "C" JNIEXPORT void JNICALL
@ -241,7 +251,10 @@ JNI_DECLARE(LorieService, touchMotion)(unused JNIEnv *env, unused jobject instan
LorieBackendAndroid *b = fromLong(jcompositor);
LOGV("JNI: touch motion");
b->touch_motion(static_cast<uint32_t>(id), static_cast<uint32_t>(x), static_cast<uint32_t>(y));
b->post([b, id, x, y]() {
b->touch_motion(static_cast<uint32_t>(id), static_cast<uint32_t>(x),
static_cast<uint32_t>(y));
});
}
extern "C" JNIEXPORT void JNICALL
@ -250,7 +263,9 @@ JNI_DECLARE(LorieService, touchUp)(unused JNIEnv *env, unused jobject instance,
LorieBackendAndroid *b = fromLong(jcompositor);
LOGV("JNI: touch up");
b->touch_up(static_cast<uint32_t>(id));
b->post([b, id]() {
b->touch_up(static_cast<uint32_t>(id));
});
}
extern "C" JNIEXPORT void JNICALL
@ -259,7 +274,9 @@ JNI_DECLARE(LorieService, touchFrame)(unused JNIEnv *env, unused jobject instanc
LorieBackendAndroid *b = fromLong(jcompositor);
LOGV("JNI: touch frame");
b->touch_frame();
b->post([b]() {
b->touch_frame();
});
}
extern "C" JNIEXPORT void JNICALL
@ -268,7 +285,9 @@ JNI_DECLARE(LorieService, pointerMotion)(unused JNIEnv *env, unused jobject inst
LorieBackendAndroid *b = fromLong(jcompositor);
LOGV("JNI: pointer motion %dx%d", x, y);
b->pointer_motion(static_cast<uint32_t>(x), static_cast<uint32_t>(y));
b->post([b, x, y](){
b->pointer_motion(static_cast<uint32_t>(x), static_cast<uint32_t>(y));
});
}
extern "C" JNIEXPORT void JNICALL
@ -277,7 +296,9 @@ JNI_DECLARE(LorieService, pointerScroll)(unused JNIEnv *env, unused jobject inst
LorieBackendAndroid *b = fromLong(jcompositor);
LOGV("JNI: pointer scroll %d %f", axis, value);
b->pointer_scroll(static_cast<uint32_t>(axis), value);
b->post([b, axis, value]() {
b->pointer_scroll(static_cast<uint32_t>(axis), value);
});
}
extern "C" JNIEXPORT void JNICALL
@ -286,7 +307,9 @@ JNI_DECLARE(LorieService, pointerButton)(unused JNIEnv *env, unused jobject inst
LorieBackendAndroid *b = fromLong(jcompositor);
LOGV("JNI: pointer button %d type %d", button, type);
b->pointer_button(static_cast<uint32_t>(button), static_cast<uint32_t>(type));
b->post([b, button, type]() {
b->pointer_button(static_cast<uint32_t>(button), static_cast<uint32_t>(type));
});
}
extern "C" void get_character_data(char** layout, int *shift, int *ec, char *ch);
@ -300,23 +323,29 @@ JNI_DECLARE(LorieService, keyboardKey)(JNIEnv *env, unused jobject instance,
if (jcompositor == 0) return;
LorieBackendAndroid *b = fromLong(jcompositor);
char *characters = NULL;
char *characters = nullptr;
int event_code = 0;
int shift = jshift;
if (characters_ != NULL) characters = (char*) env->GetStringUTFChars(characters_, 0);
if (characters_ != nullptr) characters = (char*) env->GetStringUTFChars(characters_, nullptr);
if (key_code && !characters) {
android_keycode_get_eventcode(key_code, &event_code, &shift);
LOGE("kc: %d ec: %d", key_code, event_code);
if (strcmp(b->xkb_names.layout, "us") && event_code != 0) {
b->queue.call(&LorieBackendAndroid::layout_change_callback, b, (char*)"us");
}
if (strcmp(b->xkb_names.layout, "us") != 0) {
if (event_code != 0) {
b->post([b](){
b->layout_change_callback((char *) "us");
});
}
}
}
if (!key_code && characters) {
char *layout = NULL;
char *layout = nullptr;
get_character_data(&layout, &shift, &event_code, characters);
if (layout && b->xkb_names.layout != layout) {
b->queue.call(&LorieBackendAndroid::layout_change_callback, b, layout);
b->post([b, layout](){
b->layout_change_callback(layout);
});
}
}
LOGE("Keyboard input: keyCode: %d; eventCode: %d; characters: %s; shift: %d, type: %d", key_code, event_code, characters, shift, type);
@ -330,18 +359,26 @@ JNI_DECLARE(LorieService, keyboardKey)(JNIEnv *env, unused jobject instance,
//}
if (shift || jshift)
b->keyboard_key(42, WL_KEYBOARD_KEY_STATE_PRESSED); // Send KEY_LEFTSHIFT
b->post([b]() {
b->keyboard_key(42, WL_KEYBOARD_KEY_STATE_PRESSED); // Send KEY_LEFTSHIFT
});
// For some reason Android do not send ACTION_DOWN for non-English characters
if (characters)
b->keyboard_key(static_cast<uint32_t>(event_code), WL_KEYBOARD_KEY_STATE_PRESSED);
b->post([b, event_code]() {
b->keyboard_key(static_cast<uint32_t>(event_code), WL_KEYBOARD_KEY_STATE_PRESSED);
});
b->keyboard_key(static_cast<uint32_t>(event_code), static_cast<uint32_t>(type));
b->post([b, event_code, type]() {
b->keyboard_key(static_cast<uint32_t>(event_code), static_cast<uint32_t>(type));
});
if (shift || jshift)
b->keyboard_key(42, WL_KEYBOARD_KEY_STATE_RELEASED); // Send KEY_LEFTSHIFT
b->post([b]() {
b->keyboard_key(42, WL_KEYBOARD_KEY_STATE_RELEASED); // Send KEY_LEFTSHIFT
});
if (characters_ != NULL) env->ReleaseStringUTFChars(characters_, characters);
if (characters_ != nullptr) env->ReleaseStringUTFChars(characters_, characters);
}
static bool sameUid(int pid) {
@ -357,12 +394,12 @@ static void killAllLogcats() {
struct dirent* dir_elem;
char path[64] = {0}, link[64] = {0};
pid_t pid, self = getpid();
if ((proc = opendir("/proc")) == NULL) {
if ((proc = opendir("/proc")) == nullptr) {
LOGE("opendir: %s", strerror(errno));
return;
}
while((dir_elem = readdir(proc)) != NULL) {
while((dir_elem = readdir(proc)) != nullptr) {
if (!(pid = (pid_t) atoi (dir_elem->d_name)) || pid == self || !sameUid(pid))
continue;
@ -373,7 +410,7 @@ static void killAllLogcats() {
LOGE("readlink %s: %s", path, strerror(errno));
continue;
}
if (strstr(link, "/logcat") != NULL) {
if (strstr(link, "/logcat") != nullptr) {
if (kill(pid, SIGKILL) < 0) {
LOGE("kill %d (%s): %s", pid, link, strerror);
}
@ -390,19 +427,19 @@ void fork(std::function<void()> f) {
}
extern "C" JNIEXPORT void JNICALL
Java_com_termux_x11_LorieService_startLogcatForFd(unused JNIEnv *env, unused jobject thiz, jint fd) {
Java_com_termux_x11_LorieService_startLogcatForFd(unused JNIEnv *env, unused jclass clazz, jint fd) {
killAllLogcats();
LOGI("Starting logcat with output to given fd");
fork([]() {
execl("/system/bin/logcat", "logcat", "-c", NULL);
execl("/system/bin/logcat", "logcat", "-c", nullptr);
LOGE("exec logcat: %s", strerror(errno));
});
fork([fd]() {
dup2(fd, 1);
dup2(fd, 2);
execl("/system/bin/logcat", "logcat", NULL);
execl("/system/bin/logcat", "logcat", nullptr);
LOGE("exec logcat: %s", strerror(errno));
});
}
}

View File

@ -10,23 +10,6 @@
#define LOGV(fmt ...)
LorieCompositor::LorieCompositor() :
#define wrapper(name) \
name(&LorieCompositor::real_ ## name, this, queue)
wrapper(terminate),
wrapper(output_redraw),
wrapper(output_resize),
wrapper(touch_down),
wrapper(touch_motion),
wrapper(touch_up),
wrapper(touch_frame),
wrapper(pointer_motion),
wrapper(pointer_scroll),
wrapper(pointer_button),
wrapper(keyboard_key),
wrapper(keyboard_key_modifiers),
wrapper(keyboard_keymap_changed),
#undef wrapper
renderer(*this),
toplevel(renderer.toplevel_surface),
cursor(renderer.cursor_surface),
@ -61,6 +44,10 @@ void LorieCompositor::start() {
wl_display_run(display);
}
void LorieCompositor::post(std::function<void()> f) {
queue.write(f);
}
struct wl_event_source* LorieCompositor::add_fd_listener(int fd, uint32_t mask, wl_event_loop_fd_func_t func, void *data) {
LOGV("Adding fd %d to event loop", fd);
struct wl_event_loop* loop = nullptr;
@ -73,7 +60,7 @@ struct wl_event_source* LorieCompositor::add_fd_listener(int fd, uint32_t mask,
return nullptr;
}
void LorieCompositor::real_terminate() {
void LorieCompositor::terminate() {
LOGV("Terminating compositor");
if (display != nullptr)
wl_display_terminate(display);
@ -87,19 +74,21 @@ void LorieCompositor::set_cursor(LorieSurface *surface, uint32_t hotspot_x, uint
renderer.set_cursor(surface, hotspot_x, hotspot_y);
}
void LorieCompositor::real_output_redraw() {
void LorieCompositor::output_redraw() {
LOGV("Requested redraw");
renderer.requestRedraw();
}
void LorieCompositor::real_output_resize(uint32_t width, uint32_t height, uint32_t physical_width, uint32_t physical_height) {
void LorieCompositor::output_resize(uint32_t width, uint32_t height, uint32_t physical_width, uint32_t physical_height) {
// Xwayland segfaults without that line
if (width == 0 || height == 0 || physical_width == 0 || physical_height == 0) return;
renderer.resize(width, height, physical_width, physical_height);
output_redraw();
post([this]() {
output_redraw();
});
}
void LorieCompositor::real_touch_down(uint32_t id, uint32_t x, uint32_t y) {
void LorieCompositor::touch_down(uint32_t id, uint32_t x, uint32_t y) {
LorieClient *client = get_toplevel_client();
if (toplevel == nullptr || client == nullptr) return;
@ -110,7 +99,7 @@ void LorieCompositor::real_touch_down(uint32_t id, uint32_t x, uint32_t y) {
renderer.setCursorVisibility(false);
}
void LorieCompositor::real_touch_motion(uint32_t id, uint32_t x, uint32_t y) {
void LorieCompositor::touch_motion(uint32_t id, uint32_t x, uint32_t y) {
LorieClient *client = get_toplevel_client();
if (toplevel == nullptr || client == nullptr) return;
@ -121,7 +110,7 @@ void LorieCompositor::real_touch_motion(uint32_t id, uint32_t x, uint32_t y) {
renderer.setCursorVisibility(false);
}
void LorieCompositor::real_touch_up(uint32_t id) {
void LorieCompositor::touch_up(uint32_t id) {
LorieClient *client = get_toplevel_client();
if (toplevel == nullptr || client == nullptr) return;
@ -129,7 +118,7 @@ void LorieCompositor::real_touch_up(uint32_t id) {
renderer.setCursorVisibility(false);
}
void LorieCompositor::real_touch_frame() {
void LorieCompositor::touch_frame() {
LorieClient *client = get_toplevel_client();
if (toplevel == nullptr || client == nullptr) return;
@ -137,7 +126,7 @@ void LorieCompositor::real_touch_frame() {
renderer.setCursorVisibility(false);
}
void LorieCompositor::real_pointer_motion(uint32_t x, uint32_t y) {
void LorieCompositor::pointer_motion(uint32_t x, uint32_t y) {
LorieClient *client = get_toplevel_client();
if (client == nullptr) return;
@ -151,7 +140,7 @@ void LorieCompositor::real_pointer_motion(uint32_t x, uint32_t y) {
renderer.cursorMove(x, y);
}
void LorieCompositor::real_pointer_scroll(uint32_t axis, float value) {
void LorieCompositor::pointer_scroll(uint32_t axis, float value) {
LorieClient *client = get_toplevel_client();
if (client == nullptr) return;
@ -163,7 +152,7 @@ void LorieCompositor::real_pointer_scroll(uint32_t axis, float value) {
renderer.setCursorVisibility(true);
}
void LorieCompositor::real_pointer_button(uint32_t button, uint32_t state) {
void LorieCompositor::pointer_button(uint32_t button, uint32_t state) {
LorieClient *client = get_toplevel_client();
if (client == nullptr) return;
@ -173,14 +162,14 @@ void LorieCompositor::real_pointer_button(uint32_t button, uint32_t state) {
renderer.setCursorVisibility(true);
}
void LorieCompositor::real_keyboard_key(uint32_t key, uint32_t state) {
void LorieCompositor::keyboard_key(uint32_t key, uint32_t state) {
LorieClient *client = get_toplevel_client();
if (client == nullptr) return;
client->keyboard.send_key (next_serial(), LorieUtils::timestamp(), key, state);
}
void LorieCompositor::real_keyboard_key_modifiers(uint8_t depressed, uint8_t latched, uint8_t locked, uint8_t group) {
void LorieCompositor::keyboard_key_modifiers(uint8_t depressed, uint8_t latched, uint8_t locked, uint8_t group) {
LorieClient *client = get_toplevel_client();
if (client == nullptr) return;
@ -197,7 +186,7 @@ void LorieCompositor::real_keyboard_key_modifiers(uint8_t depressed, uint8_t lat
client->keyboard.send_modifiers (next_serial(), depressed, latched, locked, group);
}
void LorieCompositor::real_keyboard_keymap_changed() {
void LorieCompositor::keyboard_keymap_changed() {
LorieClient *client = get_toplevel_client();
if (client == nullptr) return;

View File

@ -17,42 +17,26 @@ public:
LorieCompositor();
// compositor features
void start();
void post(std::function<void()> f);
struct wl_event_source* add_fd_listener(int fd, uint32_t mask, wl_event_loop_fd_func_t func, void *data);
void set_toplevel(LorieSurface *surface);
void set_cursor(LorieSurface *surface, uint32_t hotspot_x, uint32_t hotspot_y);
void real_terminate();
void real_output_redraw();
void real_output_resize(uint32_t width, uint32_t height, uint32_t physical_width, uint32_t physical_height);
void terminate();
void output_redraw();
void output_resize(uint32_t width, uint32_t height, uint32_t physical_width, uint32_t physical_height);
void real_touch_down(uint32_t id, uint32_t x, uint32_t y);
void real_touch_motion(uint32_t id, uint32_t x, uint32_t y);
void real_touch_up(uint32_t id);
void real_touch_frame();
void real_pointer_motion(uint32_t x, uint32_t y); // absolute values
void real_pointer_scroll(uint32_t axis, float value);
void real_pointer_button(uint32_t button, uint32_t state);
void real_keyboard_key(uint32_t key, uint32_t state);
void real_keyboard_key_modifiers(uint8_t depressed, uint8_t latched, uint8_t locked, uint8_t group);
void real_keyboard_keymap_changed();
#define wrapper(name) \
LorieFuncWrapperType<decltype(&LorieCompositor::real_ ## name)> name;
wrapper(terminate);
wrapper(output_redraw);
wrapper(output_resize);
wrapper(touch_down);
wrapper(touch_motion);
wrapper(touch_up);
wrapper(touch_frame);
wrapper(pointer_motion);
wrapper(pointer_scroll);
wrapper(pointer_button);
wrapper(keyboard_key);
wrapper(keyboard_key_modifiers);
wrapper(keyboard_keymap_changed);
#undef wrapper
void touch_down(uint32_t id, uint32_t x, uint32_t y);
void touch_motion(uint32_t id, uint32_t x, uint32_t y);
void touch_up(uint32_t id);
void touch_frame();
void pointer_motion(uint32_t x, uint32_t y); // absolute values
void pointer_scroll(uint32_t axis, float value);
void pointer_button(uint32_t button, uint32_t state);
void keyboard_key(uint32_t key, uint32_t state);
void keyboard_key_modifiers(uint8_t depressed, uint8_t latched, uint8_t locked, uint8_t group);
void keyboard_keymap_changed();
LorieRenderer renderer;

View File

@ -1,51 +1,17 @@
#pragma once
#include <functional>
#include <queue>
#include <pthread.h>
#include <mutex>
class LorieMessageQueue {
public:
LorieMessageQueue();
void write(std::function<void()> func);
template<typename Ret, typename Class, typename ... Args>
void call(Ret Class::* __pm, Args&& ... args) {
write(std::bind(std::mem_fn(__pm), args...));
};
void run();
int get_fd();
private:
int fd;
pthread_mutex_t write_mutex;
pthread_mutex_t read_mutex;
std::mutex mutex;
std::queue<std::function<void()>> queue;
};
template<class Class, class T, class... Args>
struct LorieFuncWrapper {
using TFn = T (Class::*)(Args...);
LorieFuncWrapper(TFn fn, Class* cl, LorieMessageQueue& q): cl(cl), ptr(fn), q(q) {};
Class* cl;
TFn ptr;
LorieMessageQueue& q;
T operator()(Args... params) {
q.call(ptr, cl, params...);
//return (cl->*ptr)(params...);
}
};
template<class R, class... A>
struct LorieFuncWrapperTypeHelper;
template<class R, class C, class... A>
struct LorieFuncWrapperTypeHelper<R(C::*)(A...)> {
using type = LorieFuncWrapper<C, R, A...>;
};
template <class F>
using LorieFuncWrapperType = typename LorieFuncWrapperTypeHelper<F>::type;
template<typename Ret, typename Class, typename ... Args>
LorieFuncWrapper<Class, Ret, Args...> LorieFuncWrap(Ret(Class::*F)(Args...), Class* c) {
return LorieFuncWrapper<Class, Ret, Args...>(F, c);
};

View File

@ -1,13 +1,13 @@
#include <lorie-compositor.hpp>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <cstring>
#include <cerrno>
#include <sys/eventfd.h>
#include <mutex>
LorieMessageQueue::LorieMessageQueue() {
pthread_mutex_init(&write_mutex, nullptr);
pthread_mutex_init(&read_mutex, nullptr);
std::unique_lock<std::mutex> lock(mutex);
fd = eventfd(0, EFD_CLOEXEC);
if (fd == -1) {
@ -18,21 +18,23 @@ LorieMessageQueue::LorieMessageQueue() {
void LorieMessageQueue::write(std::function<void()> func) {
static uint64_t i = 1;
pthread_mutex_lock(&write_mutex);
std::unique_lock<std::mutex> lock(mutex);
queue.push(func);
pthread_mutex_unlock(&write_mutex);
::write(fd, &i, sizeof(uint64_t));
}
void LorieMessageQueue::run() {
static uint64_t i = 0;
std::unique_lock<std::mutex> lock(mutex);
std::function<void()> fn;
::read(fd, &i, sizeof(uint64_t));
while(!queue.empty()){
queue.front()();
pthread_mutex_lock(&read_mutex);
fn = queue.front();
queue.pop();
pthread_mutex_unlock(&read_mutex);
lock.unlock();
fn();
lock.lock();
}
}