diff --git a/lib/net.js b/lib/net.js index a218ad17b48f43..298e7186aa6d60 100644 --- a/lib/net.js +++ b/lib/net.js @@ -694,7 +694,6 @@ Socket.prototype._writeGeneric = function(writev, data, encoding, cb) { } else { var enc; if (data instanceof Buffer) { - req.buffer = data; // Keep reference alive. enc = 'buffer'; } else { enc = encoding; diff --git a/src/env.h b/src/env.h index d8b6b8bb5fdfa2..0e301fb2741c97 100644 --- a/src/env.h +++ b/src/env.h @@ -69,6 +69,7 @@ namespace node { V(args_string, "args") \ V(async, "async") \ V(async_queue_string, "_asyncQueue") \ + V(buffer_string, "buffer") \ V(bytes_string, "bytes") \ V(bytes_parsed_string, "bytesParsed") \ V(bytes_read_string, "bytesRead") \ diff --git a/src/stream_base.cc b/src/stream_base.cc index 105c4ad45895c0..585b84885c77ea 100644 --- a/src/stream_base.cc +++ b/src/stream_base.cc @@ -227,6 +227,7 @@ int StreamBase::WriteBuffer(const FunctionCallbackInfo& args) { err = DoWrite(req_wrap, bufs, count, nullptr); req_wrap_obj->Set(env->async(), True(env->isolate())); + req_wrap_obj->Set(env->buffer_string(), args[1]); if (err) req_wrap->Dispose(); diff --git a/test/parallel/test-net-write-fully-async-buffer.js b/test/parallel/test-net-write-fully-async-buffer.js new file mode 100644 index 00000000000000..04fd1231fdc322 --- /dev/null +++ b/test/parallel/test-net-write-fully-async-buffer.js @@ -0,0 +1,34 @@ +'use strict'; +// Flags: --expose-gc + +// Note: This is a variant of test-net-write-fully-async-hex-string.js. +// This always worked, but it seemed appropriate to add a test that checks the +// behaviour for Buffers, too. +const common = require('../common'); +const net = require('net'); + +const data = Buffer.alloc(1000000); + +const server = net.createServer(common.mustCall(function(conn) { + conn.resume(); +})).listen(0, common.mustCall(function() { + const conn = net.createConnection(this.address().port, common.mustCall(() => { + let count = 0; + + function writeLoop() { + if (count++ === 200) { + conn.destroy(); + server.close(); + return; + } + + while (conn.write(Buffer.from(data))); + global.gc(true); + // The buffer allocated above should still be alive. + } + + conn.on('drain', writeLoop); + + writeLoop(); + })); +})); diff --git a/test/parallel/test-net-write-fully-async-hex-string.js b/test/parallel/test-net-write-fully-async-hex-string.js new file mode 100644 index 00000000000000..f3115d8d2f795e --- /dev/null +++ b/test/parallel/test-net-write-fully-async-hex-string.js @@ -0,0 +1,32 @@ +'use strict'; +// Flags: --expose-gc + +// Regression test for https://github.com/nodejs/node/issues/8251. +const common = require('../common'); +const net = require('net'); + +const data = Buffer.alloc(1000000).toString('hex'); + +const server = net.createServer(common.mustCall(function(conn) { + conn.resume(); +})).listen(0, common.mustCall(function() { + const conn = net.createConnection(this.address().port, common.mustCall(() => { + let count = 0; + + function writeLoop() { + if (count++ === 20) { + conn.destroy(); + server.close(); + return; + } + + while (conn.write(data, 'hex')); + global.gc(true); + // The buffer allocated inside the .write() call should still be alive. + } + + conn.on('drain', writeLoop); + + writeLoop(); + })); +}));