diff options
author | isaacs <i@izs.me> | 2012-01-10 12:07:30 -0800 |
---|---|---|
committer | isaacs <i@izs.me> | 2012-01-10 16:42:52 -0800 |
commit | 8cca30f31b2b71812e340692f2892fd5bf9df5db (patch) | |
tree | 496890119e0c962e05eb79b55155704c4aebaa2a /src | |
parent | 290bc0c067a63a90f3c02c4cffc4892fad7562aa (diff) | |
download | node-new-8cca30f31b2b71812e340692f2892fd5bf9df5db.tar.gz |
zlib binding cleanup
* Add assert to prevent parallel writes
* Embed request object instead of using new/delete
* Remove unnecessary WorkReqWrap in favor of uv_work_t
* Use container_of instead of req->data
Along with 2d8af39accc6e1a863aa60ed80289508f3df50e8 and
0ad2717fd88e5ddd28a1c245c78b37bfe9aa4197, this should Fix #2504.
Diffstat (limited to 'src')
-rw-r--r-- | src/node_zlib.cc | 37 |
1 files changed, 17 insertions, 20 deletions
diff --git a/src/node_zlib.cc b/src/node_zlib.cc index b3b430f3d1..19120afe30 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; @@ -83,6 +79,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; @@ -112,9 +111,9 @@ 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(); + // build up the work request + uv_work_t* work_req = &(ctx->work_req_); - req_wrap->data_ = ctx; ctx->strm_.avail_in = in_len; ctx->strm_.next_in = &(*in); ctx->strm_.avail_out = out_len; @@ -124,19 +123,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_; } @@ -146,8 +140,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 = container_of(work_req, ZCtx<mode>, work_req_); // 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 @@ -179,19 +172,18 @@ 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 = container_of(work_req, ZCtx<mode>, work_req_); 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); - // delete the ReqWrap - delete req_wrap; ctx->Unref(); } @@ -284,6 +276,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 +294,10 @@ template <node_zlib_mode mode> class ZCtx : public ObjectWrap { int flush_; int chunk_size_; + + bool write_in_progress_; + + uv_work_t work_req_; }; |