diff options
author | Kyle Edwards <kyle.edwards@kitware.com> | 2023-08-21 18:41:24 (GMT) |
---|---|---|
committer | Kyle Edwards <kyle.edwards@kitware.com> | 2023-08-25 14:44:06 (GMT) |
commit | 27be5ccd45500c055288d4d4cfcdb675eca38fee (patch) | |
tree | 1636824cff9b562a33c7bccef14225db5e1a8450 /Source/cmUVStream.h | |
parent | 5ae0030e90df07e56dc16b0210bd334650dcc9d4 (diff) | |
download | CMake-27be5ccd45500c055288d4d4cfcdb675eca38fee.zip CMake-27be5ccd45500c055288d4d4cfcdb675eca38fee.tar.gz CMake-27be5ccd45500c055288d4d4cfcdb675eca38fee.tar.bz2 |
cmUVStreamRead: Return RAII handle to avoid memory leak
Diffstat (limited to 'Source/cmUVStream.h')
-rw-r--r-- | Source/cmUVStream.h | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/Source/cmUVStream.h b/Source/cmUVStream.h index 5998256..db051b8 100644 --- a/Source/cmUVStream.h +++ b/Source/cmUVStream.h @@ -3,8 +3,11 @@ #pragma once #include <cassert> +#include <functional> #include <istream> +#include <cm/memory> + #include <cm3p/uv.h> #include "cmUVHandlePtr.h" @@ -104,28 +107,38 @@ void cmBasicUVPipeIStream<CharT, Traits>::close() using cmUVPipeIStream = cmBasicUVPipeIStream<char>; +class cmUVStreamReadHandle +{ +private: + std::vector<char> Buffer; + std::function<void(std::vector<char>)> OnRead; + std::function<void()> OnFinish; + + template <typename ReadCallback, typename FinishCallback> + friend std::unique_ptr<cmUVStreamReadHandle> cmUVStreamRead( + uv_stream_t* stream, ReadCallback onRead, FinishCallback onFinish); +}; + template <typename ReadCallback, typename FinishCallback> -void cmUVStreamRead(uv_stream_t* stream, ReadCallback onRead, - FinishCallback onFinish) +std::unique_ptr<cmUVStreamReadHandle> cmUVStreamRead(uv_stream_t* stream, + ReadCallback onRead, + FinishCallback onFinish) { - struct ReadData - { - std::vector<char> Buffer; - ReadCallback OnRead; - FinishCallback OnFinish; - }; - - stream->data = new ReadData{ {}, std::move(onRead), std::move(onFinish) }; + auto handle = cm::make_unique<cmUVStreamReadHandle>(); + handle->OnRead = std::move(onRead); + handle->OnFinish = std::move(onFinish); + + stream->data = handle.get(); uv_read_start( stream, [](uv_handle_t* s, std::size_t suggestedSize, uv_buf_t* buffer) { - auto* data = static_cast<ReadData*>(s->data); + auto* data = static_cast<cmUVStreamReadHandle*>(s->data); data->Buffer.resize(suggestedSize); buffer->base = data->Buffer.data(); buffer->len = suggestedSize; }, [](uv_stream_t* s, ssize_t nread, const uv_buf_t* buffer) { - auto* data = static_cast<ReadData*>(s->data); + auto* data = static_cast<cmUVStreamReadHandle*>(s->data); if (nread > 0) { (void)buffer; assert(buffer->base == data->Buffer.data()); @@ -134,7 +147,8 @@ void cmUVStreamRead(uv_stream_t* stream, ReadCallback onRead, } else if (nread < 0 /*|| nread == UV_EOF*/) { data->OnFinish(); uv_read_stop(s); - delete data; } }); + + return handle; } |