Created
January 10, 2012 20:50
-
-
Save isaacs/1591104 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 89ecea925bbe7253bf832aed2b8eb46694e2d12a Mon Sep 17 00:00:00 2001 | |
From: isaacs <i@izs.me> | |
Date: Tue, 10 Jan 2012 12:07:30 -0800 | |
Subject: [PATCH 1/3] zlib: Don't allow parallel writes | |
--- | |
src/node_zlib.cc | 8 ++++++++ | |
1 files changed, 8 insertions(+), 0 deletions(-) | |
diff --git a/src/node_zlib.cc b/src/node_zlib.cc | |
index b3b430f..6a0fd38 100644 | |
--- a/src/node_zlib.cc | |
+++ b/src/node_zlib.cc | |
@@ -83,6 +83,9 @@ template <node_zlib_mode mode> class ZCtx : public ObjectWrap { | |
ZCtx<mode> *ctx = ObjectWrap::Unwrap< ZCtx<mode> >(args.This()); | |
assert(ctx->init_done_ && "write before init"); | |
+ assert(!ctx->write_in_progress_ && "write already in progress"); | |
+ ctx->write_in_progress_ = true; | |
+ | |
unsigned int flush = args[0]->Uint32Value(); | |
Bytef *in; | |
Bytef *out; | |
@@ -184,6 +187,8 @@ template <node_zlib_mode mode> class ZCtx : public ObjectWrap { | |
Local<Integer> avail_out = Integer::New(ctx->strm_.avail_out); | |
Local<Integer> avail_in = Integer::New(ctx->strm_.avail_in); | |
+ ctx->write_in_progress_ = false; | |
+ | |
// call the write() cb | |
assert(req_wrap->object_->Get(callback_sym)->IsFunction() && | |
"Invalid callback"); | |
@@ -284,6 +289,7 @@ template <node_zlib_mode mode> class ZCtx : public ObjectWrap { | |
assert(0 && "wtf?"); | |
} | |
+ ctx->write_in_progress_ = false; | |
ctx->init_done_ = true; | |
assert(err == Z_OK); | |
} | |
@@ -301,6 +307,8 @@ template <node_zlib_mode mode> class ZCtx : public ObjectWrap { | |
int flush_; | |
int chunk_size_; | |
+ | |
+ bool write_in_progress_; | |
}; | |
-- | |
1.7.5.4 | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 084bbcc1923afa8895c595216d87021e94b93332 Mon Sep 17 00:00:00 2001 | |
From: isaacs <i@izs.me> | |
Date: Tue, 10 Jan 2012 12:18:18 -0800 | |
Subject: [PATCH 2/3] zlib: Embed req_wrap instead of using new/delete | |
--- | |
src/node_zlib.cc | 6 +++--- | |
1 files changed, 3 insertions(+), 3 deletions(-) | |
diff --git a/src/node_zlib.cc b/src/node_zlib.cc | |
index 6a0fd38..ba4a668 100644 | |
--- a/src/node_zlib.cc | |
+++ b/src/node_zlib.cc | |
@@ -115,7 +115,7 @@ template <node_zlib_mode mode> class ZCtx : public ObjectWrap { | |
assert(out_off + out_len <= Buffer::Length(out_buf)); | |
out = reinterpret_cast<Bytef *>(Buffer::Data(out_buf) + out_off); | |
- WorkReqWrap *req_wrap = new WorkReqWrap(); | |
+ WorkReqWrap *req_wrap = &(ctx->req_wrap_); | |
req_wrap->data_ = ctx; | |
ctx->strm_.avail_in = in_len; | |
@@ -195,8 +195,6 @@ template <node_zlib_mode mode> class ZCtx : public ObjectWrap { | |
Local<Value> args[2] = { avail_in, avail_out }; | |
MakeCallback(req_wrap->object_, "callback", 2, args); | |
- // delete the ReqWrap | |
- delete req_wrap; | |
ctx->Unref(); | |
} | |
@@ -309,6 +307,8 @@ template <node_zlib_mode mode> class ZCtx : public ObjectWrap { | |
int chunk_size_; | |
bool write_in_progress_; | |
+ | |
+ WorkReqWrap req_wrap_; | |
}; | |
-- | |
1.7.5.4 | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From fba454f592eb86b1b4176a31255b3c4e855b2dd1 Mon Sep 17 00:00:00 2001 | |
From: isaacs <i@izs.me> | |
Date: Tue, 10 Jan 2012 12:49:39 -0800 | |
Subject: [PATCH 3/3] zlib: Remove unnecessary WorkReqWrap | |
--- | |
src/node_zlib.cc | 28 +++++++++------------------- | |
1 files changed, 9 insertions(+), 19 deletions(-) | |
diff --git a/src/node_zlib.cc b/src/node_zlib.cc | |
index ba4a668..8bcab7e 100644 | |
--- a/src/node_zlib.cc | |
+++ b/src/node_zlib.cc | |
@@ -29,15 +29,11 @@ | |
#include <node.h> | |
#include <node_buffer.h> | |
-#include <req_wrap.h> | |
- | |
namespace node { | |
using namespace v8; | |
-// write() returns one of these, and then calls the cb() when it's done. | |
-typedef ReqWrap<uv_work_t> WorkReqWrap; | |
static Persistent<String> callback_sym; | |
@@ -115,9 +111,10 @@ template <node_zlib_mode mode> class ZCtx : public ObjectWrap { | |
assert(out_off + out_len <= Buffer::Length(out_buf)); | |
out = reinterpret_cast<Bytef *>(Buffer::Data(out_buf) + out_off); | |
- WorkReqWrap *req_wrap = &(ctx->req_wrap_); | |
+ // build up the work request | |
+ uv_work_t* work_req = &(ctx->work_req_); | |
+ work_req->data = ctx; | |
- req_wrap->data_ = ctx; | |
ctx->strm_.avail_in = in_len; | |
ctx->strm_.next_in = &(*in); | |
ctx->strm_.avail_out = out_len; | |
@@ -127,19 +124,14 @@ template <node_zlib_mode mode> class ZCtx : public ObjectWrap { | |
// set this so that later on, I can easily tell how much was written. | |
ctx->chunk_size_ = out_len; | |
- // build up the work request | |
- uv_work_t* work_req = &req_wrap->req_; | |
- work_req->data = req_wrap; | |
- | |
uv_queue_work(uv_default_loop(), | |
work_req, | |
ZCtx<mode>::Process, | |
ZCtx<mode>::After); | |
- req_wrap->Dispatched(); | |
ctx->Ref(); | |
- return req_wrap->object_; | |
+ return ctx->handle_; | |
} | |
@@ -149,8 +141,7 @@ template <node_zlib_mode mode> class ZCtx : public ObjectWrap { | |
// been consumed. | |
static void | |
Process(uv_work_t* work_req) { | |
- WorkReqWrap *req_wrap = reinterpret_cast<WorkReqWrap *>(work_req->data); | |
- ZCtx<mode> *ctx = (ZCtx<mode> *)req_wrap->data_; | |
+ ZCtx<mode> *ctx = (ZCtx<mode> *)work_req->data; | |
// If the avail_out is left at 0, then it means that it ran out | |
// of room. If there was avail_out left over, then it means | |
@@ -182,18 +173,17 @@ template <node_zlib_mode mode> class ZCtx : public ObjectWrap { | |
static void | |
After(uv_work_t* work_req) { | |
HandleScope scope; | |
- WorkReqWrap *req_wrap = reinterpret_cast<WorkReqWrap *>(work_req->data); | |
- ZCtx<mode> *ctx = (ZCtx<mode> *)req_wrap->data_; | |
+ ZCtx<mode> *ctx = (ZCtx<mode> *)work_req->data; | |
Local<Integer> avail_out = Integer::New(ctx->strm_.avail_out); | |
Local<Integer> avail_in = Integer::New(ctx->strm_.avail_in); | |
ctx->write_in_progress_ = false; | |
// call the write() cb | |
- assert(req_wrap->object_->Get(callback_sym)->IsFunction() && | |
+ assert(ctx->handle_->Get(callback_sym)->IsFunction() && | |
"Invalid callback"); | |
Local<Value> args[2] = { avail_in, avail_out }; | |
- MakeCallback(req_wrap->object_, "callback", 2, args); | |
+ MakeCallback(ctx->handle_, "callback", 2, args); | |
ctx->Unref(); | |
} | |
@@ -308,7 +298,7 @@ template <node_zlib_mode mode> class ZCtx : public ObjectWrap { | |
bool write_in_progress_; | |
- WorkReqWrap req_wrap_; | |
+ uv_work_t work_req_; | |
}; | |
-- | |
1.7.5.4 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment