Use uv_pipe_t for ipc
This commit is contained in:
parent
74d8cf281c
commit
a2f50f3b90
@ -5,6 +5,7 @@
|
|||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
|
#include "components/eventloop.hpp"
|
||||||
#include "components/types.hpp"
|
#include "components/types.hpp"
|
||||||
#include "events/signal_fwd.hpp"
|
#include "events/signal_fwd.hpp"
|
||||||
#include "events/signal_receiver.hpp"
|
#include "events/signal_receiver.hpp"
|
||||||
@ -53,7 +54,7 @@ class controller
|
|||||||
bool enqueue(string&& input_data);
|
bool enqueue(string&& input_data);
|
||||||
|
|
||||||
void conn_cb(int status, int events);
|
void conn_cb(int status, int events);
|
||||||
void ipc_cb(int status, int events);
|
void ipc_cb(string buf);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void read_events();
|
void read_events();
|
||||||
@ -87,6 +88,8 @@ class controller
|
|||||||
unique_ptr<ipc> m_ipc;
|
unique_ptr<ipc> m_ipc;
|
||||||
unique_ptr<inotify_watch> m_confwatch;
|
unique_ptr<inotify_watch> m_confwatch;
|
||||||
|
|
||||||
|
eventloop eloop;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief State flag
|
* \brief State flag
|
||||||
*/
|
*/
|
||||||
|
29
include/components/eventloop.hpp
Normal file
29
include/components/eventloop.hpp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <uv.h>
|
||||||
|
|
||||||
|
#include "common.hpp"
|
||||||
|
|
||||||
|
POLYBAR_NS
|
||||||
|
|
||||||
|
class eventloop {
|
||||||
|
public:
|
||||||
|
eventloop();
|
||||||
|
~eventloop();
|
||||||
|
|
||||||
|
void run();
|
||||||
|
|
||||||
|
void stop();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO remove
|
||||||
|
*/
|
||||||
|
uv_loop_t* get() const {
|
||||||
|
return m_loop.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<uv_loop_t> m_loop{nullptr};
|
||||||
|
};
|
||||||
|
|
||||||
|
POLYBAR_NS_END
|
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <uv.h>
|
||||||
|
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
#include "utils/concurrency.hpp"
|
#include "utils/concurrency.hpp"
|
||||||
@ -32,7 +34,7 @@ class ipc {
|
|||||||
explicit ipc(signal_emitter& emitter, const logger& logger);
|
explicit ipc(signal_emitter& emitter, const logger& logger);
|
||||||
~ipc();
|
~ipc();
|
||||||
|
|
||||||
void receive_message();
|
void receive_message(string buf);
|
||||||
int get_file_descriptor() const;
|
int get_file_descriptor() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -67,6 +67,7 @@ if(BUILD_LIBPOLY)
|
|||||||
${src_dir}/components/renderer.cpp
|
${src_dir}/components/renderer.cpp
|
||||||
${src_dir}/components/screen.cpp
|
${src_dir}/components/screen.cpp
|
||||||
${src_dir}/components/taskqueue.cpp
|
${src_dir}/components/taskqueue.cpp
|
||||||
|
${src_dir}/components/eventloop.cpp
|
||||||
|
|
||||||
${src_dir}/drawtypes/animation.cpp
|
${src_dir}/drawtypes/animation.cpp
|
||||||
${src_dir}/drawtypes/iconset.cpp
|
${src_dir}/drawtypes/iconset.cpp
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "components/bar.hpp"
|
#include "components/bar.hpp"
|
||||||
#include "components/builder.hpp"
|
#include "components/builder.hpp"
|
||||||
#include "components/config.hpp"
|
#include "components/config.hpp"
|
||||||
|
#include "components/eventloop.hpp"
|
||||||
#include "components/ipc.hpp"
|
#include "components/ipc.hpp"
|
||||||
#include "components/logger.hpp"
|
#include "components/logger.hpp"
|
||||||
#include "components/types.hpp"
|
#include "components/types.hpp"
|
||||||
@ -172,13 +173,13 @@ bool controller::enqueue(string&& input_data) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void controller::conn_cb(int status, int events) {
|
void controller::conn_cb(int, int) {
|
||||||
// TODO handle negative status
|
// TODO handle negative status
|
||||||
|
|
||||||
if (m_connection.connection_has_error()) {
|
if (m_connection.connection_has_error()) {
|
||||||
g_terminate = 1;
|
g_terminate = 1;
|
||||||
g_reload = 0;
|
g_reload = 0;
|
||||||
uv_stop(uv_default_loop());
|
eloop.stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,31 +195,52 @@ void controller::conn_cb(int status, int events) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void controller::ipc_cb(int status, int events) {
|
void controller::ipc_cb(string buf) {
|
||||||
// TODO handle negative status
|
// TODO handle messages sent in multiple parts.
|
||||||
m_ipc->receive_message();
|
m_ipc->receive_message(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void conn_cb_wrapper(uv_poll_t* handle, int status, int events) {
|
static void conn_cb_wrapper(uv_poll_t* handle, int status, int events) {
|
||||||
static_cast<controller*>(handle->data)->conn_cb(status, events);
|
static_cast<controller*>(handle->data)->conn_cb(status, events);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ipc_cb_wrapper(uv_poll_t* handle, int status, int events) {
|
|
||||||
static_cast<controller*>(handle->data)->ipc_cb(status, events);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void signal_cb_wrapper(uv_signal_t* handle, int signum) {
|
static void signal_cb_wrapper(uv_signal_t* handle, int signum) {
|
||||||
g_terminate = 1;
|
g_terminate = 1;
|
||||||
g_reload = (signum == SIGUSR1);
|
g_reload = (signum == SIGUSR1);
|
||||||
uv_stop(handle->loop);
|
static_cast<eventloop*>(handle->loop->data)->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void confwatch_cb_wrapper(uv_fs_event_t* handle, const char* fname, int events, int status) {
|
static void confwatch_cb_wrapper(uv_fs_event_t* handle, const char* fname, int, int) {
|
||||||
// TODO handle error
|
// TODO handle error
|
||||||
std::cout << fname << std::endl;
|
std::cout << fname << std::endl;
|
||||||
g_terminate = 1;
|
g_terminate = 1;
|
||||||
g_reload = 1;
|
g_reload = 1;
|
||||||
uv_stop(handle->loop);
|
static_cast<eventloop*>(handle->loop->data)->stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ipc_alloc_cb(uv_handle_t*, size_t, uv_buf_t* buf) {
|
||||||
|
// TODO handle alloc error
|
||||||
|
buf->base = new char[BUFSIZ];
|
||||||
|
buf->len = BUFSIZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ipc_read_cb_wrapper(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
|
||||||
|
if (nread > 0) {
|
||||||
|
string payload = string(buf->base, nread);
|
||||||
|
logger::make().notice("Bytes read: %d: '%s'", nread, payload);
|
||||||
|
static_cast<controller*>(stream->data)->ipc_cb(std::move(payload));
|
||||||
|
} else if (nread < 0) {
|
||||||
|
if (nread != UV_EOF) {
|
||||||
|
fprintf(stderr, "Read error %s\n", uv_err_name(nread));
|
||||||
|
uv_close((uv_handle_t*)stream, nullptr);
|
||||||
|
} else {
|
||||||
|
uv_read_start(stream, ipc_alloc_cb, ipc_read_cb_wrapper);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf->base) {
|
||||||
|
delete[] buf->base;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -227,7 +249,7 @@ static void confwatch_cb_wrapper(uv_fs_event_t* handle, const char* fname, int e
|
|||||||
void controller::read_events() {
|
void controller::read_events() {
|
||||||
m_log.info("Entering event loop (thread-id=%lu)", this_thread::get_id());
|
m_log.info("Entering event loop (thread-id=%lu)", this_thread::get_id());
|
||||||
|
|
||||||
auto loop = uv_default_loop();
|
auto loop = eloop.get();
|
||||||
|
|
||||||
auto conn_handle = std::make_unique<uv_poll_t>();
|
auto conn_handle = std::make_unique<uv_poll_t>();
|
||||||
uv_poll_init(loop, conn_handle.get(), m_connection.get_file_descriptor());
|
uv_poll_init(loop, conn_handle.get(), m_connection.get_file_descriptor());
|
||||||
@ -256,17 +278,17 @@ void controller::read_events() {
|
|||||||
uv_fs_event_start(conf_handle.get(), confwatch_cb_wrapper, m_confwatch->path().c_str(), 0);
|
uv_fs_event_start(conf_handle.get(), confwatch_cb_wrapper, m_confwatch->path().c_str(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ipc_handle = std::unique_ptr<uv_poll_t>(nullptr);
|
auto ipc_handle = std::unique_ptr<uv_pipe_t>(nullptr);
|
||||||
|
|
||||||
if (m_ipc) {
|
if (m_ipc) {
|
||||||
ipc_handle = std::make_unique<uv_poll_t>();
|
ipc_handle = std::make_unique<uv_pipe_t>();
|
||||||
uv_poll_init(loop, ipc_handle.get(), m_ipc->get_file_descriptor());
|
uv_pipe_init(loop, ipc_handle.get(), false);
|
||||||
ipc_handle->data = this;
|
ipc_handle->data = this;
|
||||||
uv_poll_start(ipc_handle.get(), UV_READABLE, ipc_cb_wrapper);
|
uv_pipe_open(ipc_handle.get(), m_ipc->get_file_descriptor());
|
||||||
|
uv_read_start((uv_stream_t*)ipc_handle.get(), ipc_alloc_cb, ipc_read_cb_wrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
uv_run(loop, UV_RUN_DEFAULT);
|
eloop.run();
|
||||||
uv_loop_close(loop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
30
src/components/eventloop.cpp
Normal file
30
src/components/eventloop.cpp
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#include "components/eventloop.hpp"
|
||||||
|
|
||||||
|
POLYBAR_NS
|
||||||
|
|
||||||
|
eventloop::eventloop() {
|
||||||
|
m_loop = std::make_unique<uv_loop_t>();
|
||||||
|
uv_loop_init(m_loop.get());
|
||||||
|
// TODO handle return value
|
||||||
|
|
||||||
|
m_loop->data = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
eventloop::~eventloop() {
|
||||||
|
if (m_loop) {
|
||||||
|
uv_loop_close(m_loop.get());
|
||||||
|
// TODO handle return value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void eventloop::run() {
|
||||||
|
uv_run(m_loop.get(), UV_RUN_DEFAULT);
|
||||||
|
// TODO handle return value
|
||||||
|
}
|
||||||
|
|
||||||
|
void eventloop::stop() {
|
||||||
|
uv_stop(m_loop.get());
|
||||||
|
// TODO handle return value
|
||||||
|
}
|
||||||
|
|
||||||
|
POLYBAR_NS_END
|
@ -52,29 +52,22 @@ ipc::~ipc() {
|
|||||||
/**
|
/**
|
||||||
* Receive available ipc messages and delegate valid events
|
* Receive available ipc messages and delegate valid events
|
||||||
*/
|
*/
|
||||||
void ipc::receive_message() {
|
void ipc::receive_message(string buf) {
|
||||||
m_log.info("Receiving ipc message");
|
m_log.info("Receiving ipc message");
|
||||||
|
|
||||||
char buffer[BUFSIZ]{'\0'};
|
string payload{string_util::trim(std::move(buf), '\n')};
|
||||||
ssize_t bytes_read{0};
|
|
||||||
|
|
||||||
if ((bytes_read = read(*m_fd, &buffer, BUFSIZ)) == -1) {
|
if (payload.find(ipc_command_prefix) == 0) {
|
||||||
m_log.err("Failed to read from ipc channel (err: %s)", strerror(errno));
|
m_sig.emit(signals::ipc::command{payload.substr(strlen(ipc_command_prefix))});
|
||||||
} else if (bytes_read > 0) {
|
} else if (payload.find(ipc_hook_prefix) == 0) {
|
||||||
string payload{string_util::trim(string{buffer}, '\n')};
|
m_sig.emit(signals::ipc::hook{payload.substr(strlen(ipc_hook_prefix))});
|
||||||
|
} else if (payload.find(ipc_action_prefix) == 0) {
|
||||||
if (payload.find(ipc_command_prefix) == 0) {
|
m_sig.emit(signals::ipc::action{payload.substr(strlen(ipc_action_prefix))});
|
||||||
m_sig.emit(signals::ipc::command{payload.substr(strlen(ipc_command_prefix))});
|
} else if (!payload.empty()) {
|
||||||
} else if (payload.find(ipc_hook_prefix) == 0) {
|
m_log.warn("Received unknown ipc message: (payload=%s)", payload);
|
||||||
m_sig.emit(signals::ipc::hook{payload.substr(strlen(ipc_hook_prefix))});
|
|
||||||
} else if (payload.find(ipc_action_prefix) == 0) {
|
|
||||||
m_sig.emit(signals::ipc::action{payload.substr(strlen(ipc_action_prefix))});
|
|
||||||
} else if (!payload.empty()) {
|
|
||||||
m_log.warn("Received unknown ipc message: (payload=%s)", payload);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_fd = file_util::make_file_descriptor(m_path, O_RDONLY | O_NONBLOCK);
|
/* m_fd = file_util::make_file_descriptor(m_path, O_RDONLY | O_NONBLOCK); */
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user