src: use MaybeStackBuffer on DoSend/Writev
instead of creating own buffer, use MaybeStackBuffer on DoSend to take advantage of its destructor to free up memory, so buffer never leaks memory - even if code in DoSend throws. Use MaybeStackBuffer in Writev to take advantage of destructor on MaybeStackBuffer to clear itself up, rather than Writev managing resources itself. PR-URL: https://github.com/nodejs/node/pull/8626 Reviewed-By: Anna Henningsen <anna@addaleax.net>
This commit is contained in:
parent
c1e47ed8c8
commit
fffb9a386a
@ -102,8 +102,7 @@ int StreamBase::Writev(const FunctionCallbackInfo<Value>& args) {
|
|||||||
|
|
||||||
size_t count = chunks->Length() >> 1;
|
size_t count = chunks->Length() >> 1;
|
||||||
|
|
||||||
uv_buf_t bufs_[16];
|
MaybeStackBuffer<uv_buf_t, 16> bufs(count);
|
||||||
uv_buf_t* bufs = bufs_;
|
|
||||||
|
|
||||||
// Determine storage size first
|
// Determine storage size first
|
||||||
size_t storage_size = 0;
|
size_t storage_size = 0;
|
||||||
@ -132,9 +131,6 @@ int StreamBase::Writev(const FunctionCallbackInfo<Value>& args) {
|
|||||||
if (storage_size > INT_MAX)
|
if (storage_size > INT_MAX)
|
||||||
return UV_ENOBUFS;
|
return UV_ENOBUFS;
|
||||||
|
|
||||||
if (arraysize(bufs_) < count)
|
|
||||||
bufs = new uv_buf_t[count];
|
|
||||||
|
|
||||||
WriteWrap* req_wrap = WriteWrap::New(env,
|
WriteWrap* req_wrap = WriteWrap::New(env,
|
||||||
req_wrap_obj,
|
req_wrap_obj,
|
||||||
this,
|
this,
|
||||||
@ -174,11 +170,7 @@ int StreamBase::Writev(const FunctionCallbackInfo<Value>& args) {
|
|||||||
bytes += str_size;
|
bytes += str_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
int err = DoWrite(req_wrap, bufs, count, nullptr);
|
int err = DoWrite(req_wrap, *bufs, count, nullptr);
|
||||||
|
|
||||||
// Deallocate space
|
|
||||||
if (bufs != bufs_)
|
|
||||||
delete[] bufs;
|
|
||||||
|
|
||||||
req_wrap->object()->Set(env->async(), True(env->isolate()));
|
req_wrap->object()->Set(env->async(), True(env->isolate()));
|
||||||
req_wrap->object()->Set(env->bytes_string(),
|
req_wrap->object()->Set(env->bytes_string(),
|
||||||
|
@ -275,13 +275,7 @@ void UDPWrap::DoSend(const FunctionCallbackInfo<Value>& args, int family) {
|
|||||||
SendWrap* req_wrap = new SendWrap(env, req_wrap_obj, have_callback);
|
SendWrap* req_wrap = new SendWrap(env, req_wrap_obj, have_callback);
|
||||||
size_t msg_size = 0;
|
size_t msg_size = 0;
|
||||||
|
|
||||||
// allocate uv_buf_t of the correct size
|
MaybeStackBuffer<uv_buf_t, 16> bufs(count);
|
||||||
// if bigger than 16 elements
|
|
||||||
uv_buf_t bufs_[16];
|
|
||||||
uv_buf_t* bufs = bufs_;
|
|
||||||
|
|
||||||
if (arraysize(bufs_) < count)
|
|
||||||
bufs = new uv_buf_t[count];
|
|
||||||
|
|
||||||
// construct uv_buf_t array
|
// construct uv_buf_t array
|
||||||
for (size_t i = 0; i < count; i++) {
|
for (size_t i = 0; i < count; i++) {
|
||||||
@ -313,16 +307,12 @@ void UDPWrap::DoSend(const FunctionCallbackInfo<Value>& args, int family) {
|
|||||||
if (err == 0) {
|
if (err == 0) {
|
||||||
err = uv_udp_send(&req_wrap->req_,
|
err = uv_udp_send(&req_wrap->req_,
|
||||||
&wrap->handle_,
|
&wrap->handle_,
|
||||||
bufs,
|
*bufs,
|
||||||
count,
|
count,
|
||||||
reinterpret_cast<const sockaddr*>(&addr),
|
reinterpret_cast<const sockaddr*>(&addr),
|
||||||
OnSend);
|
OnSend);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deallocate space
|
|
||||||
if (bufs != bufs_)
|
|
||||||
delete[] bufs;
|
|
||||||
|
|
||||||
req_wrap->Dispatched();
|
req_wrap->Dispatched();
|
||||||
if (err)
|
if (err)
|
||||||
delete req_wrap;
|
delete req_wrap;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user