From 99f0b022d528cc350f87150b5ecdf5c903aaeeb1 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Fri, 25 Jan 2013 16:34:54 +0400 Subject: [PATCH] stream_wrap: reference handle before uv_write2 Before sending handle to another process using uv_write2(), it should be referenced to prevent it from being GCed before AfterWrite() will be called. see #4599 --- src/stream_wrap.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/stream_wrap.cc b/src/stream_wrap.cc index 1df873412c..a0bf41e292 100644 --- a/src/stream_wrap.cc +++ b/src/stream_wrap.cc @@ -77,6 +77,7 @@ static Persistent bytes_sym; static Persistent write_queue_size_sym; static Persistent onread_sym; static Persistent oncomplete_sym; +static Persistent handle_sym; static SlabAllocator* slab_allocator; static bool initialized; @@ -411,6 +412,13 @@ Handle StreamWrap::WriteStringImpl(const Arguments& args) { StreamWrap* send_stream_wrap = static_cast( send_stream_obj->GetAlignedPointerFromInternalField(0)); send_stream = send_stream_wrap->GetStream(); + + // Reference StreamWrap instance to prevent it from being garbage + // collected before `AfterWrite` is called. + if (handle_sym.IsEmpty()) { + handle_sym = NODE_PSYMBOL("handle"); + } + req_wrap->object_->Set(handle_sym, send_stream_obj); } r = uv_write2(&req_wrap->req_, @@ -468,6 +476,9 @@ void StreamWrap::AfterWrite(uv_write_t* req, int status) { assert(req_wrap->object_.IsEmpty() == false); assert(wrap->object_.IsEmpty() == false); + // Unref handle property + req_wrap->object_->Delete(handle_sym); + if (status) { SetErrno(uv_last_error(uv_default_loop())); }