[net2] inline write on empty write buffer for performance
This commit is contained in:
parent
1762abcece
commit
90295d9fce
83
lib/net.js
83
lib/net.js
@ -501,6 +501,83 @@ Stream.prototype.write = function (data, encoding) {
|
||||
|
||||
if (!self.writable) throw new Error('Stream is not writable');
|
||||
|
||||
if (self._writeQueue && self._writeQueue.length) {
|
||||
return self._writeQueued(data, encoding); // slow
|
||||
|
||||
} else {
|
||||
// The most common case. There is no write queue. Just push the data
|
||||
// directly to the socket.
|
||||
|
||||
var bytesWritten;
|
||||
var buffer = data, off = 0, len = data.length;
|
||||
|
||||
if (typeof data == 'string') {
|
||||
encoding = (encoding || 'utf8').toLowerCase();
|
||||
var bytes = encoding == 'utf8' ? Buffer.utf8ByteLength(data) : data.length;
|
||||
|
||||
//debug('write string :' + JSON.stringify(data));
|
||||
|
||||
if (!recvBuffer) allocRecvBuffer();
|
||||
|
||||
if (recvBuffer.length - recvBuffer.used < bytes) {
|
||||
// not enough room - go to slow case
|
||||
return self._writeQueued(data, encoding);
|
||||
}
|
||||
|
||||
var charsWritten;
|
||||
if (encoding == 'utf8') {
|
||||
recvBuffer.utf8Write(data, recvBuffer.used);
|
||||
} else {
|
||||
// ascii
|
||||
recvBuffer.asciiWrite(data, recvBuffer.used);
|
||||
}
|
||||
|
||||
buffer = recvBuffer;
|
||||
off = recvBuffer.used;
|
||||
len = bytes;
|
||||
}
|
||||
|
||||
//debug('write [fd, off, len] =' + JSON.stringify([self.fd, off, len]));
|
||||
|
||||
// Send the buffer.
|
||||
try {
|
||||
bytesWritten = write(self.fd, buffer, off, len);
|
||||
} catch (e) {
|
||||
self.forceClose(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
//debug('wrote ' + bytesWritten);
|
||||
|
||||
// Note: if using the recvBuffer - we don't need to increase
|
||||
// recvBuffer.used because it was all sent. Just reuse that space.
|
||||
|
||||
if (bytesWritten == len) return true;
|
||||
|
||||
//debug('write incomplete ' + bytesWritten + ' < ' + len);
|
||||
|
||||
if (buffer == data) {
|
||||
data.sent = bytesWritten || 0;
|
||||
data.used = data.length;
|
||||
} else {
|
||||
// string
|
||||
recvBuffer.used += bytesWritten;
|
||||
data = recvBuffer.slice(off+bytesWritten, off+len+bytesWritten);
|
||||
data.sent = 0;
|
||||
data.used = data.length;
|
||||
}
|
||||
|
||||
//if (!self._writeQueue) initWriteStream(self);
|
||||
self._writeQueue.push(data);
|
||||
self._writeQueueSize += data.used;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Stream.prototype._writeQueued = function (data, encoding) {
|
||||
//debug('_writeQueued');
|
||||
var self = this;
|
||||
|
||||
if (self.__writeQueueLast() == END_OF_FILE) {
|
||||
throw new Error('socket.close() called already; cannot write.');
|
||||
}
|
||||
@ -597,7 +674,7 @@ Stream.prototype.flush = function () {
|
||||
} else {
|
||||
b.sent += bytesWritten;
|
||||
self._writeQueueSize -= bytesWritten;
|
||||
debug('bytes sent: ' + b.sent);
|
||||
//debug('bytes sent: ' + b.sent);
|
||||
}
|
||||
}
|
||||
if (self._writeWatcher) self._writeWatcher.stop();
|
||||
@ -654,7 +731,7 @@ Stream.prototype.connect = function () {
|
||||
|
||||
if (port >= 0) {
|
||||
self.fd = socket('tcp');
|
||||
debug('new fd = ' + self.fd);
|
||||
//debug('new fd = ' + self.fd);
|
||||
self.type = 'tcp';
|
||||
// TODO dns resolution on arguments[1]
|
||||
var port = arguments[0];
|
||||
@ -726,7 +803,7 @@ Stream.prototype.forceClose = function (exception) {
|
||||
// FIXME Bug when this.fd == 0
|
||||
if (this.fd) {
|
||||
close(this.fd);
|
||||
debug('close ' + this.fd);
|
||||
//debug('close ' + this.fd);
|
||||
this.fd = null;
|
||||
process.nextTick(function () {
|
||||
if (exception) self.emit('error', exception);
|
||||
|
@ -20,6 +20,7 @@ function pingPongTest (port, host) {
|
||||
socket.setNoDelay();
|
||||
socket.timeout = 0;
|
||||
|
||||
socket.setEncoding('utf8');
|
||||
socket.addListener("data", function (data) {
|
||||
puts("server got: " + data);
|
||||
assert.equal(true, socket.writable);
|
||||
@ -53,6 +54,7 @@ function pingPongTest (port, host) {
|
||||
|
||||
var client = net.createConnection(port, host);
|
||||
|
||||
client.setEncoding('ascii');
|
||||
client.addListener("connect", function () {
|
||||
assert.equal(true, client.readable);
|
||||
assert.equal(true, client.writable);
|
||||
@ -106,4 +108,5 @@ pingPongTest("/tmp/pingpong.sock");
|
||||
|
||||
process.addListener("exit", function () {
|
||||
assert.equal(4, tests_run);
|
||||
puts('done');
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user