diff --git a/wpiutil/src/main/native/cpp/uv/Tcp.cpp b/wpiutil/src/main/native/cpp/uv/Tcp.cpp index e8a8127ec6..7bd4c4e3b5 100644 --- a/wpiutil/src/main/native/cpp/uv/Tcp.cpp +++ b/wpiutil/src/main/native/cpp/uv/Tcp.cpp @@ -25,6 +25,26 @@ std::shared_ptr Tcp::Create(Loop& loop, unsigned int flags) { return h; } +void Tcp::Reuse(std::function callback, unsigned int flags) { + if (!IsClosing()) { + m_reuseData = std::make_unique(); + m_reuseData->callback = callback; + m_reuseData->flags = flags; + uv_close(GetRawHandle(), [](uv_handle_t* handle) { + Tcp& h = *static_cast(handle->data); + if (!h.m_reuseData) return; // just in case + auto data = std::move(h.m_reuseData); + int err = + uv_tcp_init_ex(h.GetLoopRef().GetRaw(), h.GetRaw(), data->flags); + if (err < 0) { + h.ReportError(err); + return; + } + data->callback(); + }); + } +} + std::shared_ptr Tcp::Accept() { auto client = Create(GetLoopRef()); if (!client) return nullptr; diff --git a/wpiutil/src/main/native/include/wpi/uv/Tcp.h b/wpiutil/src/main/native/include/wpi/uv/Tcp.h index 38b9624088..791c80d1f2 100644 --- a/wpiutil/src/main/native/include/wpi/uv/Tcp.h +++ b/wpiutil/src/main/native/include/wpi/uv/Tcp.h @@ -56,6 +56,18 @@ class Tcp final : public NetworkStreamImpl { return Create(*loop, flags); } + /** + * 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 flags Flags + * @param callback Callback + */ + void Reuse(std::function callback, unsigned int flags = AF_UNSPEC); + /** * Accept incoming connection. * @@ -304,6 +316,12 @@ class Tcp final : public NetworkStreamImpl { private: Tcp* DoAccept() override; + + struct ReuseData { + std::function callback; + unsigned int flags; + }; + std::unique_ptr m_reuseData; }; /**