summaryrefslogtreecommitdiffstats
path: root/Source/cmUVStream.h
diff options
context:
space:
mode:
authorKyle Edwards <kyle.edwards@kitware.com>2023-08-21 18:41:24 (GMT)
committerKyle Edwards <kyle.edwards@kitware.com>2023-08-25 14:44:06 (GMT)
commit27be5ccd45500c055288d4d4cfcdb675eca38fee (patch)
tree1636824cff9b562a33c7bccef14225db5e1a8450 /Source/cmUVStream.h
parent5ae0030e90df07e56dc16b0210bd334650dcc9d4 (diff)
downloadCMake-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.h40
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;
}