Browse Source

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
v0.9.9-release
Fedor Indutny 12 years ago
parent
commit
99f0b022d5
  1. 11
      src/stream_wrap.cc

11
src/stream_wrap.cc

@ -77,6 +77,7 @@ static Persistent<String> bytes_sym;
static Persistent<String> write_queue_size_sym; static Persistent<String> write_queue_size_sym;
static Persistent<String> onread_sym; static Persistent<String> onread_sym;
static Persistent<String> oncomplete_sym; static Persistent<String> oncomplete_sym;
static Persistent<String> handle_sym;
static SlabAllocator* slab_allocator; static SlabAllocator* slab_allocator;
static bool initialized; static bool initialized;
@ -411,6 +412,13 @@ Handle<Value> StreamWrap::WriteStringImpl(const Arguments& args) {
StreamWrap* send_stream_wrap = static_cast<StreamWrap*>( StreamWrap* send_stream_wrap = static_cast<StreamWrap*>(
send_stream_obj->GetAlignedPointerFromInternalField(0)); send_stream_obj->GetAlignedPointerFromInternalField(0));
send_stream = send_stream_wrap->GetStream(); 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_, 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(req_wrap->object_.IsEmpty() == false);
assert(wrap->object_.IsEmpty() == false); assert(wrap->object_.IsEmpty() == false);
// Unref handle property
req_wrap->object_->Delete(handle_sym);
if (status) { if (status) {
SetErrno(uv_last_error(uv_default_loop())); SetErrno(uv_last_error(uv_default_loop()));
} }

Loading…
Cancel
Save