Skip to content

Commit 49efb20

Browse files
mcollinajasnell
authored andcommitted
streams: support unlimited synchronous cork/uncork cycles
net streams can request multiple chunks to be written in a synchronous fashion. If this is combined with cork/uncork, en error is currently thrown because of a regression introduced in: 89aeab9 (#4354). Fixes: #6154 PR-URL: #6164 Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Mathias Buus <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 71bdf86 commit 49efb20

File tree

2 files changed

+50
-6
lines changed

2 files changed

+50
-6
lines changed

lib/_stream_writable.js

+9-6
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,9 @@ function WritableState(options, stream) {
112112
// count buffered requests
113113
this.bufferedRequestCount = 0;
114114

115-
// create the two objects needed to store the corked requests
116-
// they are not a linked list, as no new elements are inserted in there
115+
// allocate the first CorkedRequest, there is always
116+
// one allocated and free to use, and we maintain at most two
117117
this.corkedRequestsFree = new CorkedRequest(this);
118-
this.corkedRequestsFree.next = new CorkedRequest(this);
119118
}
120119

121120
WritableState.prototype.getBuffer = function writableStateGetBuffer() {
@@ -387,12 +386,16 @@ function clearBuffer(stream, state) {
387386

388387
doWrite(stream, state, true, state.length, buffer, '', holder.finish);
389388

390-
// doWrite is always async, defer these to save a bit of time
389+
// doWrite is almost always async, defer these to save a bit of time
391390
// as the hot path ends with doWrite
392391
state.pendingcb++;
393392
state.lastBufferedRequest = null;
394-
state.corkedRequestsFree = holder.next;
395-
holder.next = null;
393+
if (holder.next) {
394+
state.corkedRequestsFree = holder.next;
395+
holder.next = null;
396+
} else {
397+
state.corkedRequestsFree = new CorkedRequest(state);
398+
}
396399
} else {
397400
// Slow case, write chunks one-by-one
398401
while (entry) {

test/parallel/test-net-sync-cork.js

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const assert = require('assert');
5+
const net = require('net');
6+
7+
const server = net.createServer(handle);
8+
9+
const N = 100;
10+
const buf = Buffer.alloc(2, 'a');
11+
12+
server.listen(common.PORT, function() {
13+
const conn = net.connect(common.PORT);
14+
15+
conn.on('connect', () => {
16+
let res = true;
17+
let i = 0;
18+
for (; i < N && res; i++) {
19+
conn.cork();
20+
conn.write(buf);
21+
res = conn.write(buf);
22+
conn.uncork();
23+
}
24+
assert.equal(i, N);
25+
conn.end();
26+
});
27+
});
28+
29+
process.on('exit', function() {
30+
assert.equal(server.connections, 0);
31+
});
32+
33+
function handle(socket) {
34+
socket.resume();
35+
36+
socket.on('error', function(err) {
37+
socket.destroy();
38+
}).on('close', function() {
39+
server.close();
40+
});
41+
}

0 commit comments

Comments
 (0)