diff options
author | Fedor Indutny <fedor.indutny@gmail.com> | 2013-01-25 16:34:54 +0400 |
---|---|---|
committer | Fedor Indutny <fedor.indutny@gmail.com> | 2013-01-26 22:38:00 +0400 |
commit | 99f0b022d528cc350f87150b5ecdf5c903aaeeb1 (patch) | |
tree | 0625ed338aaf90ebf64f5a60962b6b9d972baca3 /src/stream_wrap.cc | |
parent | bdc7251b64bf2a467fb7048cff5dc1814f3152ed (diff) | |
download | android-node-v8-99f0b022d528cc350f87150b5ecdf5c903aaeeb1.tar.gz android-node-v8-99f0b022d528cc350f87150b5ecdf5c903aaeeb1.tar.bz2 android-node-v8-99f0b022d528cc350f87150b5ecdf5c903aaeeb1.zip |
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
Diffstat (limited to 'src/stream_wrap.cc')
-rw-r--r-- | src/stream_wrap.cc | 11 |
1 files changed, 11 insertions, 0 deletions
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<String> bytes_sym; static Persistent<String> write_queue_size_sym; static Persistent<String> onread_sym; static Persistent<String> oncomplete_sym; +static Persistent<String> handle_sym; static SlabAllocator* slab_allocator; static bool initialized; @@ -411,6 +412,13 @@ Handle<Value> StreamWrap::WriteStringImpl(const Arguments& args) { StreamWrap* send_stream_wrap = static_cast<StreamWrap*>( 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())); } |