diff options
author | Brad King <brad.king@kitware.com> | 2023-10-31 14:11:20 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2023-11-22 12:12:38 (GMT) |
commit | 7ee5fb01c62952c3e8b10afb646be772a6eb47af (patch) | |
tree | 78ed9476ef50a5bbe220470244bd1d15f066eada /Source/cmUVHandlePtr.cxx | |
parent | bec0dd93a3174b1f636ce4548ea6ea837b62df32 (diff) | |
download | CMake-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.cxx | 37 |
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; +} } |