Skip to content

Instantly share code, notes, and snippets.

@isaacs
Created January 10, 2012 20:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save isaacs/1591104 to your computer and use it in GitHub Desktop.
Save isaacs/1591104 to your computer and use it in GitHub Desktop.
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
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
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