summaryrefslogtreecommitdiffstats
path: root/Source/cmUVHandlePtr.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2023-10-31 14:11:20 (GMT)
committerBrad King <brad.king@kitware.com>2023-11-22 12:12:38 (GMT)
commit7ee5fb01c62952c3e8b10afb646be772a6eb47af (patch)
tree78ed9476ef50a5bbe220470244bd1d15f066eada /Source/cmUVHandlePtr.cxx
parentbec0dd93a3174b1f636ce4548ea6ea837b62df32 (diff)
downloadCMake-7ee5fb01c62952c3e8b10afb646be772a6eb47af.zip
CMake-7ee5fb01c62952c3e8b10afb646be772a6eb47af.tar.gz
CMake-7ee5fb01c62952c3e8b10afb646be772a6eb47af.tar.bz2
cmUVHandlePtr: Add uv_write wrapper to manage request lifetime
Provide a way to synchronously cancel a write request callback.
Diffstat (limited to 'Source/cmUVHandlePtr.cxx')
-rw-r--r--Source/cmUVHandlePtr.cxx37
1 files changed, 37 insertions, 0 deletions
diff --git a/Source/cmUVHandlePtr.cxx b/Source/cmUVHandlePtr.cxx
index 7d41644..168f1a6 100644
--- a/Source/cmUVHandlePtr.cxx
+++ b/Source/cmUVHandlePtr.cxx
@@ -6,6 +6,9 @@
#include <cassert>
#include <cstdlib>
#include <mutex>
+#include <utility>
+
+#include <cm/memory>
#include <cm3p/uv.h>
@@ -306,4 +309,38 @@ UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(async)
UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(tty)
#endif
+
+namespace {
+struct write_req : public uv_write_t
+{
+ std::weak_ptr<std::function<void(int)>> cb_;
+ write_req(std::weak_ptr<std::function<void(int)>> wcb)
+ : cb_(std::move(wcb))
+ {
+ }
+};
+
+void write_req_cb(uv_write_t* req, int status)
+{
+ // Ownership has been transferred from the event loop.
+ std::unique_ptr<write_req> self(static_cast<write_req*>(req));
+
+ // Notify the original uv_write caller if it is still interested.
+ if (auto cb = self->cb_.lock()) {
+ (*cb)(status);
+ }
+}
+}
+
+int uv_write(uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs,
+ std::weak_ptr<std::function<void(int)>> cb)
+{
+ auto req = cm::make_unique<write_req>(std::move(cb));
+ int status = uv_write(req.get(), handle, bufs, nbufs, write_req_cb);
+ if (status == 0) {
+ // Ownership has been transferred to the event loop.
+ static_cast<void>(req.release());
+ }
+ return status;
+}
}