From 76d9e266338e2a5c2248e3c424d2b9d884f1cc7c Mon Sep 17 00:00:00 2001 From: Thad House Date: Sat, 9 Feb 2019 00:09:22 -0800 Subject: [PATCH] uv: Add reuse to pipe (#1577) Needed for a reconnection API --- wpiutil/src/main/native/cpp/uv/Pipe.cpp | 19 +++++++++++++++++++ wpiutil/src/main/native/include/wpi/uv/Pipe.h | 18 ++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/wpiutil/src/main/native/cpp/uv/Pipe.cpp b/wpiutil/src/main/native/cpp/uv/Pipe.cpp index dae0f00d18..8d4ee76d3c 100644 --- a/wpiutil/src/main/native/cpp/uv/Pipe.cpp +++ b/wpiutil/src/main/native/cpp/uv/Pipe.cpp @@ -25,6 +25,25 @@ std::shared_ptr Pipe::Create(Loop& loop, bool ipc) { return h; } +void Pipe::Reuse(std::function callback, bool ipc) { + if (IsClosing()) return; + if (!m_reuseData) m_reuseData = std::make_unique(); + m_reuseData->callback = callback; + m_reuseData->ipc = ipc; + uv_close(GetRawHandle(), [](uv_handle_t* handle) { + Pipe& h = *static_cast(handle->data); + if (!h.m_reuseData) return; + auto data = std::move(h.m_reuseData); + auto err = + uv_pipe_init(h.GetLoopRef().GetRaw(), h.GetRaw(), data->ipc ? 1 : 0); + if (err < 0) { + h.ReportError(err); + return; + } + data->callback(); + }); +} + std::shared_ptr Pipe::Accept() { auto client = Create(GetLoopRef(), GetRaw()->ipc); if (!client) return nullptr; diff --git a/wpiutil/src/main/native/include/wpi/uv/Pipe.h b/wpiutil/src/main/native/include/wpi/uv/Pipe.h index b4d8af2dbc..304ccbb9d8 100644 --- a/wpiutil/src/main/native/include/wpi/uv/Pipe.h +++ b/wpiutil/src/main/native/include/wpi/uv/Pipe.h @@ -56,6 +56,18 @@ class Pipe final : public NetworkStreamImpl { return Create(*loop, ipc); } + /** + * Reuse this handle. This closes the handle, and after the close completes, + * reinitializes it (identically to Create) and calls the provided callback. + * Unlike Close(), it does NOT emit the closed signal, however, IsClosing() + * will return true until the callback is called. This does nothing if + * IsClosing() is true (e.g. if Close() was called). + * + * @param ipc IPC + * @param callback Callback + */ + void Reuse(std::function callback, bool ipc = false); + /** * Accept incoming connection. * @@ -176,6 +188,12 @@ class Pipe final : public NetworkStreamImpl { private: Pipe* DoAccept() override; + + struct ReuseData { + std::function callback; + bool ipc; + }; + std::unique_ptr m_reuseData; }; /**