Create wrapper for uv_pipe_t
This commit is contained in:
parent
86f02a3ebe
commit
309fd8221a
@ -3,8 +3,8 @@
|
|||||||
#include <moodycamel/blockingconcurrentqueue.h>
|
#include <moodycamel/blockingconcurrentqueue.h>
|
||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
|
|
||||||
#include <thread>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
#include "components/eventloop.hpp"
|
#include "components/eventloop.hpp"
|
||||||
|
@ -13,12 +13,13 @@ POLYBAR_NS
|
|||||||
* Runs any libuv function with an integer error code return value and throws an
|
* Runs any libuv function with an integer error code return value and throws an
|
||||||
* exception on error.
|
* exception on error.
|
||||||
*/
|
*/
|
||||||
#define UV(fun, ...) \
|
#define UV(fun, ...) \
|
||||||
do { \
|
do { \
|
||||||
int res = fun(__VA_ARGS__); \
|
int res = fun(__VA_ARGS__); \
|
||||||
if (res < 0) { \
|
if (res < 0) { \
|
||||||
throw std::runtime_error("libuv error for '" #fun "': "s + uv_strerror(res)); \
|
throw std::runtime_error( \
|
||||||
} \
|
__FILE__ ":"s + std::to_string(__LINE__) + ": libuv error for '" #fun "': "s + uv_strerror(res)); \
|
||||||
|
} \
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
template <class H, class... Args>
|
template <class H, class... Args>
|
||||||
@ -31,6 +32,10 @@ struct cb_helper {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \tparam H Type of the handle
|
||||||
|
* \tparam I Type of the handle passed to the callback. Often the same as H, but not always (e.g. uv_read_start)
|
||||||
|
*/
|
||||||
template <typename H, typename I, typename... Args>
|
template <typename H, typename I, typename... Args>
|
||||||
struct UVHandleGeneric {
|
struct UVHandleGeneric {
|
||||||
UVHandleGeneric(std::function<void(Args...)> fun) {
|
UVHandleGeneric(std::function<void(Args...)> fun) {
|
||||||
@ -81,43 +86,45 @@ struct FSEventHandle : public UVHandle<uv_fs_event_t, const char*, int, int> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct PipeHandle : public UVHandleGeneric<uv_pipe_t, uv_stream_t, ssize_t, const uv_buf_t*> {
|
struct PipeHandle : public UVHandleGeneric<uv_pipe_t, uv_stream_t, ssize_t, const uv_buf_t*> {
|
||||||
PipeHandle(uv_loop_t* loop, std::function<void(const string)> fun)
|
std::function<void(const string)> func;
|
||||||
: UVHandleGeneric([&](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);
|
|
||||||
fun(std::move(payload));
|
|
||||||
} else if (nread < 0) {
|
|
||||||
if (nread != UV_EOF) {
|
|
||||||
logger::make().err("Read error: %s", uv_err_name(nread));
|
|
||||||
uv_close((uv_handle_t*)handle.get(), nullptr);
|
|
||||||
} else {
|
|
||||||
UV(
|
|
||||||
uv_read_start, (uv_stream_t*)handle.get(),
|
|
||||||
[](uv_handle_t*, size_t, uv_buf_t* buf) {
|
|
||||||
buf->base = new char[BUFSIZ];
|
|
||||||
buf->len = BUFSIZ;
|
|
||||||
},
|
|
||||||
&cb.callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf->base) {
|
int fd;
|
||||||
delete[] buf->base;
|
|
||||||
}
|
PipeHandle(uv_loop_t* loop, std::function<void(const string)> fun)
|
||||||
}) {
|
: UVHandleGeneric([&](ssize_t nread, const uv_buf_t* buf) { read_cb(nread, buf); }), func(fun) {
|
||||||
UV(uv_pipe_init, loop, handle.get(), false);
|
UV(uv_pipe_init, loop, handle.get(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void start(int fd) {
|
void start(int fd) {
|
||||||
|
this->fd = fd;
|
||||||
UV(uv_pipe_open, handle.get(), fd);
|
UV(uv_pipe_open, handle.get(), fd);
|
||||||
UV(
|
UV(uv_read_start, (uv_stream_t*)handle.get(), alloc_cb, &cb.callback);
|
||||||
uv_read_start, (uv_stream_t*)handle.get(),
|
}
|
||||||
[](uv_handle_t*, size_t, uv_buf_t* buf) {
|
|
||||||
buf->base = new char[BUFSIZ];
|
static void alloc_cb(uv_handle_t*, size_t, uv_buf_t* buf) {
|
||||||
buf->len = BUFSIZ;
|
buf->base = new char[BUFSIZ];
|
||||||
},
|
buf->len = BUFSIZ;
|
||||||
&cb.callback);
|
}
|
||||||
|
|
||||||
|
void read_cb(ssize_t nread, const uv_buf_t* buf) {
|
||||||
|
auto log = logger::make();
|
||||||
|
if (nread > 0) {
|
||||||
|
string payload = string(buf->base, nread);
|
||||||
|
log.notice("Bytes read: %d: '%s'", nread, payload);
|
||||||
|
func(payload);
|
||||||
|
} else if (nread < 0) {
|
||||||
|
if (nread != UV_EOF) {
|
||||||
|
log.err("Read error: %s", uv_err_name(nread));
|
||||||
|
uv_close((uv_handle_t*)handle.get(), nullptr);
|
||||||
|
} else {
|
||||||
|
// TODO this causes constant EOFs
|
||||||
|
start(this->fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf->base) {
|
||||||
|
delete[] buf->base;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -237,30 +237,6 @@ void controller::notifier_handler() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ipc_alloc_cb(uv_handle_t*, size_t, uv_buf_t* buf) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void notifier_cb_wrapper(uv_async_t* handle) {
|
static void notifier_cb_wrapper(uv_async_t* handle) {
|
||||||
static_cast<controller*>(handle->data)->notifier_handler();
|
static_cast<controller*>(handle->data)->notifier_handler();
|
||||||
}
|
}
|
||||||
@ -284,7 +260,7 @@ void controller::read_events(bool confwatch) {
|
|||||||
m_bar->start();
|
m_bar->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ipc_handle = std::unique_ptr<uv_pipe_t>(nullptr);
|
auto ipc_handle = std::unique_ptr<PipeHandle>(nullptr);
|
||||||
auto screenshot_timer_handle = std::unique_ptr<uv_timer_t>(nullptr);
|
auto screenshot_timer_handle = std::unique_ptr<uv_timer_t>(nullptr);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -304,11 +280,8 @@ void controller::read_events(bool confwatch) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_ipc) {
|
if (m_ipc) {
|
||||||
ipc_handle = std::make_unique<uv_pipe_t>();
|
ipc_handle = std::make_unique<PipeHandle>(loop, [this](const string payload) { ipc_cb(payload); });
|
||||||
UV(uv_pipe_init, loop, ipc_handle.get(), false);
|
ipc_handle->start(m_ipc->get_file_descriptor());
|
||||||
ipc_handle->data = this;
|
|
||||||
UV(uv_pipe_open, ipc_handle.get(), m_ipc->get_file_descriptor());
|
|
||||||
UV(uv_read_start, (uv_stream_t*)ipc_handle.get(), ipc_alloc_cb, ipc_read_cb_wrapper);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_notifier = std::make_unique<uv_async_t>();
|
m_notifier = std::make_unique<uv_async_t>();
|
||||||
|
@ -30,7 +30,7 @@ eventloop::~eventloop() {
|
|||||||
close_loop(m_loop.get());
|
close_loop(m_loop.get());
|
||||||
UV(uv_loop_close, m_loop.get());
|
UV(uv_loop_close, m_loop.get());
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
// TODO log error
|
logger::make().err("%s", e.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
m_loop.reset();
|
m_loop.reset();
|
||||||
|
Loading…
Reference in New Issue
Block a user