diff options
author | Jun Ma <roammm@gmail.com> | 2014-01-26 01:50:17 +0800 |
---|---|---|
committer | Fedor Indutny <fedor.indutny@gmail.com> | 2014-01-27 22:12:29 +0400 |
commit | d2de8ba34dc57d78a0bd0fedc4bd05e5c4457bac (patch) | |
tree | 70c974efad38e007c09035fd4c2fb16889edc4c4 | |
parent | b4c4e0bbaa19616f41857e20c2dc2824c780baf4 (diff) | |
download | node-d2de8ba34dc57d78a0bd0fedc4bd05e5c4457bac.tar.gz |
net: make Socket destroy() re-entrance safe
So that we are free to call socket.destroy() in error event handler.
fix #6769
-rw-r--r-- | lib/net.js | 5 | ||||
-rw-r--r-- | test/simple/test-net-stream.js | 33 |
2 files changed, 37 insertions, 1 deletions
diff --git a/lib/net.js b/lib/net.js index e624adfcc..31de90cb0 100644 --- a/lib/net.js +++ b/lib/net.js @@ -469,8 +469,11 @@ Socket.prototype._destroy = function(exception, cb) { this._handle = null; } - fireErrorCallbacks(); + // we set destroyed to true before firing error callbacks in order + // to make it re-entrance safe in case Socket.prototype.destroy() + // is called within callbacks this.destroyed = true; + fireErrorCallbacks(); if (this.server) { COUNTER_NET_SERVER_CONNECTION_CLOSE(this); diff --git a/test/simple/test-net-stream.js b/test/simple/test-net-stream.js index 429995ab9..9f2db51be 100644 --- a/test/simple/test-net-stream.js +++ b/test/simple/test-net-stream.js @@ -37,3 +37,36 @@ s.destroy(); assert.equal(9, s.server.connections); s.destroy(); assert.equal(9, s.server.connections); + +var SIZE = 2E6; +var N = 10; +var buf = new Buffer(SIZE); +buf.fill(0x61); // 'a' + +var server = net.createServer(function(socket) { + socket.setNoDelay(); + + socket.on('error', function(err) { + socket.destroy(); + }).on('close', function() { + server.close(); + }) + + for (var i = 0; i < N; ++i) { + socket.write(buf, function() { }); + } + socket.end(); + +}).listen(common.PORT, function() { + var conn = net.connect(common.PORT); + conn.on('data', function(buf) { + conn.pause(); + setTimeout(function() { + conn.destroy(); + }, 20); + }); + }); + +process.on('exit', function() { + assert.equal(server.connections, 0); +}); |