summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/slab_allocator.cc3
-rw-r--r--src/stream_wrap.cc15
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);