Skip to content


zlib: emit "close" if Z_STREAM_END occurs. #3747

wants to merge 2 commits into from

4 participants


In src/, Z_OK, Z_STREAM_END and Z_BUF_ERROR has been ignored because they are considered normal statuses.

But Z_STREAM_END must be handled. Even if zlib does not end when it meets Z_STREAM_END, it should at least tell user so that user can stop it.

(Actaully, I believe "end" is better than "close" for this case, but emitting "end" may cause exception because zlib does not allow to write something to itself if zlib._ended is true.)


This isn't quite accurate.

Z_STREAM_END is the return value if all the output is consumed, and the flush param was set to Z_FINISH. However, the "close" event should be used only when the underlying resource is completely disposed of (ie, when deflateEnd or inflateEnd has been successfully called to free the memory.) This would occur when the binding has been deleted, but we don't actually track that, and just let that happen when V8's garbage collector cleans things up.

However, upon receiving a Z_STREAM_END, you can call .reset() on the stream, and then re-use it again. In fact, this is a useful way to prevent having to create new underlying objects.

What we probably ought to do is remove the place where we're currently emitting "end", and only emit "end" when a Z_STREAM_END return value is encountered. Would you like to change your patch to do that?

@npcode npcode zlib: Emit "end" instead of "close" for Z_STREAM_END
Emit "end" instead of "close" when Z_STREAM_END return value is
encountered. And remove emitting "end" in Zlib.end().

You are right, @isaacs . I have done as you said and it looks to work well.


Can one of the admins verify this patch?

Node.js Foundation member

I guess it isn't relevant anymore?

@indutny indutny closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jul 20, 2012
  1. @npcode
  2. @npcode

    zlib: Emit "end" instead of "close" for Z_STREAM_END

    npcode committed
    Emit "end" instead of "close" when Z_STREAM_END return value is
    encountered. And remove emitting "end" in Zlib.end().
Showing with 7 additions and 3 deletions.
  1. +5 −2 lib/zlib.js
  2. +2 −1 src/
7 lib/zlib.js
@@ -346,7 +346,6 @@ Zlib.prototype.end = function end(chunk, cb) {
var self = this;
this._ending = true;
var ret = this.write(chunk, function() {
- self.emit('end');
if (cb) cb();
this._ended = true;
@@ -392,7 +391,7 @@ Zlib.prototype._process = function() {
req.callback = callback;
this._processing = req;
- function callback(availInAfter, availOutAfter, buffer) {
+ function callback(err, availInAfter, availOutAfter, buffer) {
if (self._hadError) return;
var have = availOutBefore - availOutAfter;
@@ -438,6 +437,10 @@ Zlib.prototype._process = function() {
self._processing = false;
if (cb) cb();
+ if (err == binding.Z_STREAM_END) {
+ self.emit('end');
+ }
3 src/
@@ -211,7 +211,8 @@ class ZCtx : public ObjectWrap {
// call the write() cb
assert(ctx->handle_->Get(callback_sym)->IsFunction() &&
"Invalid callback");
- Local<Value> args[2] = { avail_in, avail_out };
+ Local<Value> args[3] = { Local<Value>::New(Number::New(ctx->err_)),
+ avail_in, avail_out };
MakeCallback(ctx->handle_, callback_sym, ARRAY_SIZE(args), args);
Something went wrong with that request. Please try again.