|
@ -178,6 +178,7 @@ function initStream(self) { |
|
|
self._writeQueue = []; |
|
|
self._writeQueue = []; |
|
|
self._writeQueueEncoding = []; |
|
|
self._writeQueueEncoding = []; |
|
|
self._writeQueueFD = []; |
|
|
self._writeQueueFD = []; |
|
|
|
|
|
self._writeQueueCallbacks = []; |
|
|
|
|
|
|
|
|
self._writeWatcher = ioWatchers.alloc(); |
|
|
self._writeWatcher = ioWatchers.alloc(); |
|
|
self._writeWatcher.socket = self; |
|
|
self._writeWatcher.socket = self; |
|
@ -296,6 +297,7 @@ Stream.prototype.write = function(data /* [encoding], [fd], [cb] */) { |
|
|
this._writeQueue = []; |
|
|
this._writeQueue = []; |
|
|
this._writeQueueEncoding = []; |
|
|
this._writeQueueEncoding = []; |
|
|
this._writeQueueFD = []; |
|
|
this._writeQueueFD = []; |
|
|
|
|
|
this._writeQueueCallbacks = []; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Slow. There is already a write queue, so let's append to it.
|
|
|
// Slow. There is already a write queue, so let's append to it.
|
|
@ -311,9 +313,22 @@ Stream.prototype.write = function(data /* [encoding], [fd], [cb] */) { |
|
|
this._writeQueueEncoding[last] === encoding) { |
|
|
this._writeQueueEncoding[last] === encoding) { |
|
|
// optimization - concat onto last
|
|
|
// optimization - concat onto last
|
|
|
this._writeQueue[last] += data; |
|
|
this._writeQueue[last] += data; |
|
|
|
|
|
|
|
|
|
|
|
if (cb) { |
|
|
|
|
|
if (!this._writeQueueCallbacks[last]) { |
|
|
|
|
|
this._writeQueueCallbacks[last] = cb; |
|
|
|
|
|
} else { |
|
|
|
|
|
// awful
|
|
|
|
|
|
this._writeQueueCallbacks[last] = function () { |
|
|
|
|
|
this._writeQueueCallbacks[last](); |
|
|
|
|
|
cb(); |
|
|
|
|
|
}; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
this._writeQueue.push(data); |
|
|
this._writeQueue.push(data); |
|
|
this._writeQueueEncoding.push(encoding); |
|
|
this._writeQueueEncoding.push(encoding); |
|
|
|
|
|
this._writeQueueCallbacks.push(cb); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (fd != undefined) { |
|
|
if (fd != undefined) { |
|
@ -325,7 +340,7 @@ Stream.prototype.write = function(data /* [encoding], [fd], [cb] */) { |
|
|
// Fast.
|
|
|
// Fast.
|
|
|
// The most common case. There is no write queue. Just push the data
|
|
|
// The most common case. There is no write queue. Just push the data
|
|
|
// directly to the socket.
|
|
|
// directly to the socket.
|
|
|
return this._writeOut(data, encoding, fd); |
|
|
return this._writeOut(data, encoding, fd, cb); |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
@ -337,7 +352,7 @@ Stream.prototype.write = function(data /* [encoding], [fd], [cb] */) { |
|
|
// 2. Write data to socket. Return true if flushed.
|
|
|
// 2. Write data to socket. Return true if flushed.
|
|
|
// 3. Slice out remaining
|
|
|
// 3. Slice out remaining
|
|
|
// 4. Unshift remaining onto _writeQueue. Return false.
|
|
|
// 4. Unshift remaining onto _writeQueue. Return false.
|
|
|
Stream.prototype._writeOut = function(data, encoding, fd) { |
|
|
Stream.prototype._writeOut = function(data, encoding, fd, cb) { |
|
|
if (!this.writable) { |
|
|
if (!this.writable) { |
|
|
throw new Error('Stream is not writable'); |
|
|
throw new Error('Stream is not writable'); |
|
|
} |
|
|
} |
|
@ -388,6 +403,7 @@ Stream.prototype._writeOut = function(data, encoding, fd) { |
|
|
// Unshift whatever didn't fit onto the buffer
|
|
|
// Unshift whatever didn't fit onto the buffer
|
|
|
this._writeQueue.unshift(data.slice(charsWritten)); |
|
|
this._writeQueue.unshift(data.slice(charsWritten)); |
|
|
this._writeQueueEncoding.unshift(encoding); |
|
|
this._writeQueueEncoding.unshift(encoding); |
|
|
|
|
|
this._writeQueueCallbacks.unshift(cb); |
|
|
this._writeWatcher.start(); |
|
|
this._writeWatcher.start(); |
|
|
queuedData = true; |
|
|
queuedData = true; |
|
|
} |
|
|
} |
|
@ -416,6 +432,7 @@ Stream.prototype._writeOut = function(data, encoding, fd) { |
|
|
if (queuedData) { |
|
|
if (queuedData) { |
|
|
return false; |
|
|
return false; |
|
|
} else { |
|
|
} else { |
|
|
|
|
|
if (cb) cb(); |
|
|
return true; |
|
|
return true; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -434,6 +451,7 @@ Stream.prototype._writeOut = function(data, encoding, fd) { |
|
|
// data should be the next thing to write.
|
|
|
// data should be the next thing to write.
|
|
|
this._writeQueue.unshift(leftOver); |
|
|
this._writeQueue.unshift(leftOver); |
|
|
this._writeQueueEncoding.unshift(null); |
|
|
this._writeQueueEncoding.unshift(null); |
|
|
|
|
|
this._writeQueueCallbacks.unshift(cb); |
|
|
|
|
|
|
|
|
// If didn't successfully write any bytes, enqueue our fd and try again
|
|
|
// If didn't successfully write any bytes, enqueue our fd and try again
|
|
|
if (!bytesWritten) { |
|
|
if (!bytesWritten) { |
|
@ -450,6 +468,7 @@ Stream.prototype.flush = function() { |
|
|
while (this._writeQueue && this._writeQueue.length) { |
|
|
while (this._writeQueue && this._writeQueue.length) { |
|
|
var data = this._writeQueue.shift(); |
|
|
var data = this._writeQueue.shift(); |
|
|
var encoding = this._writeQueueEncoding.shift(); |
|
|
var encoding = this._writeQueueEncoding.shift(); |
|
|
|
|
|
var cb = this._writeQueueCallbacks.shift(); |
|
|
var fd = this._writeQueueFD.shift(); |
|
|
var fd = this._writeQueueFD.shift(); |
|
|
|
|
|
|
|
|
if (data === END_OF_FILE) { |
|
|
if (data === END_OF_FILE) { |
|
@ -457,7 +476,7 @@ Stream.prototype.flush = function() { |
|
|
return true; |
|
|
return true; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
var flushed = this._writeOut(data, encoding, fd); |
|
|
var flushed = this._writeOut(data, encoding, fd, cb); |
|
|
if (!flushed) return false; |
|
|
if (!flushed) return false; |
|
|
} |
|
|
} |
|
|
if (this._writeWatcher) this._writeWatcher.stop(); |
|
|
if (this._writeWatcher) this._writeWatcher.stop(); |
|
|