summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJun Ma <roammm@gmail.com>2014-01-26 01:50:17 +0800
committerFedor Indutny <fedor.indutny@gmail.com>2014-01-27 22:12:29 +0400
commitd2de8ba34dc57d78a0bd0fedc4bd05e5c4457bac (patch)
tree70c974efad38e007c09035fd4c2fb16889edc4c4
parentb4c4e0bbaa19616f41857e20c2dc2824c780baf4 (diff)
downloadnode-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.js5
-rw-r--r--test/simple/test-net-stream.js33
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);
+});