// or on a later tick.
this.sync = false;
+ // a flag to know if we're processing previously buffered items, which
+ // may call the _write() callback in the same tick, so that we don't
+ // end up in an overlapped onwrite situation.
+ this.bufferProcessing = false;
+
// the callback that's passed to _write(chunk,cb)
this.onwrite = function(er) {
onwrite(stream, er);
if (cb) {
// Don't call the cb until the next tick if we're in sync mode.
- // Also defer if we're about to write some more right now.
- if (sync || state.buffer.length)
+ if (sync)
process.nextTick(cb);
else
cb();
return;
}
- // if there's something in the buffer waiting, then do that, too.
- if (state.buffer.length) {
- var chunkCb = state.buffer.shift();
- 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;
- stream._write(chunk, state.onwrite);
- }
-
if (state.length <= state.lowWaterMark && state.needDrain) {
// Must force callback to be called on nextTick, so that we don't
// emit 'drain' before the write() consumer gets the 'false' return
});
});
+var lastCalled = -1;
+function makeCallback(c) {
+ var called = false;
+ return function() {
+ if (called)
+ throw new Error('called callback #' + c + ' more than once');
+ called = true;
+ if (c < lastCalled)
+ throw new Error('callbacks out of order. last=' + lastCalled +
+ ' current=' + c);
+ lastCalled = c;
+ cbcount++;
+ };
+}
+
server.listen(common.PORT, function() {
var client = net.createConnection(common.PORT);
client.on('connect', function() {
for (var i = 0; i < N; i++) {
- client.write('hello world', function() {
- cbcount++;
- });
+ client.write('hello world', makeCallback(i));
}
client.end();
});