diff options
-rw-r--r-- | src/slab_allocator.cc | 3 | ||||
-rw-r--r-- | src/stream_wrap.cc | 15 |
2 files changed, 13 insertions, 5 deletions
diff --git a/src/slab_allocator.cc b/src/slab_allocator.cc index 504557a55..45daf621a 100644 --- a/src/slab_allocator.cc +++ b/src/slab_allocator.cc @@ -116,7 +116,8 @@ Local<Object> SlabAllocator::Shrink(Handle<Object> obj, assert(!slab_v.IsEmpty()); assert(slab_v->IsObject()); Local<Object> slab = slab_v->ToObject(); - if (ptr && ptr == last_ptr_) { + assert(ptr != NULL); + if (ptr == last_ptr_) { last_ptr_ = NULL; offset_ = ptr - Buffer::Data(slab) + ROUND_UP(size, 16); } diff --git a/src/stream_wrap.cc b/src/stream_wrap.cc index 515fa9f41..234aa3dc2 100644 --- a/src/stream_wrap.cc +++ b/src/stream_wrap.cc @@ -162,16 +162,23 @@ void StreamWrap::OnReadCommon(uv_stream_t* handle, ssize_t nread, // uv_close() on the handle. assert(wrap->object_.IsEmpty() == false); - Local<Object> slab = slab_allocator.Shrink(wrap->object_, - buf.base, - nread < 0 ? 0 : nread); - if (nread < 0) { + // If libuv reports an error or EOF it *may* give us a buffer back. In that + // case, return the space to the slab. + if (buf.base != NULL) { + slab_allocator.Shrink(wrap->object_, buf.base, 0); + } + SetErrno(uv_last_error(uv_default_loop())); MakeCallback(wrap->object_, "onread", 0, NULL); return; } + assert(buf.base != NULL); + Local<Object> slab = slab_allocator.Shrink(wrap->object_, + buf.base, + nread); + if (nread == 0) return; assert(static_cast<size_t>(nread) <= buf.len); |