aboutsummaryrefslogtreecommitdiff
path: root/src/stream_wrap.cc
diff options
context:
space:
mode:
authorFedor Indutny <fedor.indutny@gmail.com>2013-01-25 16:34:54 +0400
committerFedor Indutny <fedor.indutny@gmail.com>2013-01-26 22:38:00 +0400
commit99f0b022d528cc350f87150b5ecdf5c903aaeeb1 (patch)
tree0625ed338aaf90ebf64f5a60962b6b9d972baca3 /src/stream_wrap.cc
parentbdc7251b64bf2a467fb7048cff5dc1814f3152ed (diff)
downloadandroid-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.cc11
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()));
}