diff options
author | isaacs <i@izs.me> | 2012-12-19 09:04:08 -0800 |
---|---|---|
committer | isaacs <i@izs.me> | 2012-12-19 10:55:23 -0800 |
commit | 9f4c0988c37b9df60e45c26c25c91e45757d8f62 (patch) | |
tree | 147c78c32841cfd7651ecbad1b0c20eae5564861 | |
parent | cab22644a5bbeba5091790f767d37783e79c4401 (diff) | |
download | node-9f4c0988c37b9df60e45c26c25c91e45757d8f62.tar.gz |
streams2: Process write buffer in a loop, not recursively
This fixes pummel/test-net-write-callbacks
-rw-r--r-- | lib/_stream_writable.js | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/lib/_stream_writable.js b/lib/_stream_writable.js index d2e3d8fc4..3b015663e 100644 --- a/lib/_stream_writable.js +++ b/lib/_stream_writable.js @@ -219,6 +219,49 @@ function onwrite(stream, er) { stream.emit('drain'); }); } + + // if there's something in the buffer waiting, then process it + // It would be nice if there were TCO in JS, and we could just + // shift the top off the buffer and _write that, but that approach + // causes RangeErrors when you have a very large number of very + // small writes, and is not very efficient otherwise. + if (!state.bufferProcessing && state.buffer.length) { + state.bufferProcessing = true; + + for (var c = 0; c < state.buffer.length; c++) { + var chunkCb = state.buffer[c]; + var chunk = chunkCb[0]; + cb = chunkCb[1]; + + if (false === state.decodeStrings) + l = chunk[0].length; + else + l = chunk.length; + + state.writelen = l; + state.writecb = cb; + state.writechunk = chunk; + state.writing = true; + state.sync = true; + stream._write(chunk, state.onwrite); + state.sync = false; + + // if we didn't call the onwrite immediately, then + // it means that we need to wait until it does. + // also, that means that the chunk and cb are currently + // being processed, so move the buffer counter past them. + if (state.writing) { + c++; + break; + } + } + + state.bufferProcessing = false; + if (c < state.buffer.length) + state.buffer = state.buffer.slice(c); + else + state.buffer.length = 0; + } } Writable.prototype._write = function(chunk, cb) { |