zlib: do not emit event on *Sync() methods
Asynchronous functions in `zlib` should not emit the close event. This fixes an issue where asynchronous calls in a for loop could exhaust memory because the pending event prevents the objects from being garbage collected. Fixes: https://github.com/nodejs/node/issues/1668 PR-URL: https://github.com/nodejs/node/pull/5707 Reviewed-By: jasnell - James M Snell <jasnell@gmail.com> Reviewed-By: trevnorris - Trevor Norris <trev.norris@gmail.com> Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com>
This commit is contained in:
parent
a53b2ac4b1
commit
8b43d3f52d
19
lib/zlib.js
19
lib/zlib.js
@ -454,18 +454,21 @@ Zlib.prototype.flush = function(kind, callback) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Zlib.prototype.close = function(callback) {
|
Zlib.prototype.close = function(callback) {
|
||||||
|
_close(this, callback);
|
||||||
|
process.nextTick(emitCloseNT, this);
|
||||||
|
};
|
||||||
|
|
||||||
|
function _close(engine, callback) {
|
||||||
if (callback)
|
if (callback)
|
||||||
process.nextTick(callback);
|
process.nextTick(callback);
|
||||||
|
|
||||||
if (this._closed)
|
if (engine._closed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this._closed = true;
|
engine._closed = true;
|
||||||
|
|
||||||
this._handle.close();
|
engine._handle.close();
|
||||||
|
}
|
||||||
process.nextTick(emitCloseNT, this);
|
|
||||||
};
|
|
||||||
|
|
||||||
function emitCloseNT(self) {
|
function emitCloseNT(self) {
|
||||||
self.emit('close');
|
self.emit('close');
|
||||||
@ -535,12 +538,12 @@ Zlib.prototype._processChunk = function(chunk, flushFlag, cb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (nread >= kMaxLength) {
|
if (nread >= kMaxLength) {
|
||||||
this.close();
|
_close(this);
|
||||||
throw new RangeError(kRangeErrorMessage);
|
throw new RangeError(kRangeErrorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
var buf = Buffer.concat(buffers, nread);
|
var buf = Buffer.concat(buffers, nread);
|
||||||
this.close();
|
_close(this);
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
21
test/parallel/test-zlib-sync-no-event.js
Normal file
21
test/parallel/test-zlib-sync-no-event.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
'use strict';
|
||||||
|
require('../common');
|
||||||
|
const zlib = require('zlib');
|
||||||
|
const assert = require('assert');
|
||||||
|
|
||||||
|
const shouldNotBeCalled = () => { throw new Error('unexpected event'); };
|
||||||
|
|
||||||
|
const message = 'Come on, Fhqwhgads.';
|
||||||
|
|
||||||
|
const zipper = new zlib.Gzip();
|
||||||
|
zipper.on('close', shouldNotBeCalled);
|
||||||
|
|
||||||
|
const buffer = new Buffer(message);
|
||||||
|
const zipped = zipper._processChunk(buffer, zlib.Z_FINISH);
|
||||||
|
|
||||||
|
const unzipper = new zlib.Gunzip();
|
||||||
|
unzipper.on('close', shouldNotBeCalled);
|
||||||
|
|
||||||
|
const unzipped = unzipper._processChunk(zipped, zlib.Z_FINISH);
|
||||||
|
assert.notEqual(zipped.toString(), message);
|
||||||
|
assert.strictEqual(unzipped.toString(), message);
|
Loading…
x
Reference in New Issue
Block a user