diff --git a/include/components/eventloop.hpp b/include/components/eventloop.hpp index 1bd92d49..9f3cdf40 100644 --- a/include/components/eventloop.hpp +++ b/include/components/eventloop.hpp @@ -31,16 +31,21 @@ struct cb_helper { } }; -template -struct UVHandle { - UVHandle(std::function fun) { +template +struct UVHandleGeneric { + UVHandleGeneric(std::function fun) { handle = std::make_unique(); - cb = cb_helper{fun}; + cb = cb_helper{fun}; handle->data = &cb; } std::unique_ptr handle; - cb_helper cb; + cb_helper cb; +}; + +template +struct UVHandle : public UVHandleGeneric { + UVHandle(std::function fun) : UVHandleGeneric(fun) {} }; struct SignalHandle : public UVHandle { @@ -75,6 +80,47 @@ struct FSEventHandle : public UVHandle { } }; +struct PipeHandle : public UVHandleGeneric { + PipeHandle(uv_loop_t* loop, std::function fun) + : 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) { + delete[] buf->base; + } + }) { + UV(uv_pipe_init, loop, handle.get(), false); + } + + void start(int fd) { + UV(uv_pipe_open, handle.get(), fd); + 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); + } +}; + class eventloop { public: eventloop();