@@ -5,6 +5,7 @@ const util = require('util');
5
5
const Socket = require ( 'net' ) . Socket ;
6
6
const JSStream = process . binding ( 'js_stream' ) . JSStream ;
7
7
const uv = process . binding ( 'uv' ) ;
8
+ const debug = util . debuglog ( 'stream_wrap' ) ;
8
9
9
10
function StreamWrap ( stream ) {
10
11
const handle = new JSStream ( ) ;
@@ -15,6 +16,7 @@ function StreamWrap(stream) {
15
16
16
17
const self = this ;
17
18
handle . close = function ( cb ) {
19
+ debug ( 'close' ) ;
18
20
self . doClose ( cb ) ;
19
21
} ;
20
22
handle . isAlive = function ( ) {
@@ -40,18 +42,23 @@ function StreamWrap(stream) {
40
42
this . stream . on ( 'error' , function ( err ) {
41
43
self . emit ( 'error' , err ) ;
42
44
} ) ;
43
-
44
- Socket . call ( this , {
45
- handle : handle
46
- } ) ;
47
-
48
45
this . stream . on ( 'data' , function ( chunk ) {
49
- if ( self . _handle )
50
- self . _handle . readBuffer ( chunk ) ;
46
+ setImmediate ( function ( ) {
47
+ debug ( 'data' , chunk . length ) ;
48
+ if ( self . _handle )
49
+ self . _handle . readBuffer ( chunk ) ;
50
+ } ) ;
51
51
} ) ;
52
52
this . stream . once ( 'end' , function ( ) {
53
- if ( self . _handle )
54
- self . _handle . emitEOF ( ) ;
53
+ setImmediate ( function ( ) {
54
+ debug ( 'end' ) ;
55
+ if ( self . _handle )
56
+ self . _handle . emitEOF ( ) ;
57
+ } ) ;
58
+ } ) ;
59
+
60
+ Socket . call ( this , {
61
+ handle : handle
55
62
} ) ;
56
63
}
57
64
util . inherits ( StreamWrap , Socket ) ;
@@ -61,11 +68,11 @@ module.exports = StreamWrap;
61
68
StreamWrap . StreamWrap = StreamWrap ;
62
69
63
70
StreamWrap . prototype . isAlive = function isAlive ( ) {
64
- return this . readable && this . writable ;
71
+ return true ;
65
72
} ;
66
73
67
74
StreamWrap . prototype . isClosing = function isClosing ( ) {
68
- return ! this . isAlive ( ) ;
75
+ return ! this . readable || ! this . writable ;
69
76
} ;
70
77
71
78
StreamWrap . prototype . readStart = function readStart ( ) {
@@ -79,11 +86,16 @@ StreamWrap.prototype.readStop = function readStop() {
79
86
} ;
80
87
81
88
StreamWrap . prototype . doShutdown = function doShutdown ( req ) {
89
+ const self = this ;
82
90
const handle = this . _handle ;
91
+ const item = this . _enqueue ( 'shutdown' , req ) ;
83
92
84
93
this . stream . end ( function ( ) {
85
94
// Ensure that write was dispatched
86
95
setImmediate ( function ( ) {
96
+ if ( ! self . _dequeue ( item ) )
97
+ return ;
98
+
87
99
handle . finishShutdown ( req , 0 ) ;
88
100
} ) ;
89
101
} ) ;
@@ -97,7 +109,7 @@ StreamWrap.prototype.doWrite = function doWrite(req, bufs) {
97
109
var pending = bufs . length ;
98
110
99
111
// Queue the request to be able to cancel it
100
- self . _enqueue ( req ) ;
112
+ const item = self . _enqueue ( 'write' , req ) ;
101
113
102
114
self . stream . cork ( ) ;
103
115
bufs . forEach ( function ( buf ) {
@@ -115,7 +127,7 @@ StreamWrap.prototype.doWrite = function doWrite(req, bufs) {
115
127
// Ensure that write was dispatched
116
128
setImmediate ( function ( ) {
117
129
// Do not invoke callback twice
118
- if ( ! self . _dequeue ( req ) )
130
+ if ( ! self . _dequeue ( item ) )
119
131
return ;
120
132
121
133
var errCode = 0 ;
@@ -134,39 +146,47 @@ StreamWrap.prototype.doWrite = function doWrite(req, bufs) {
134
146
return 0 ;
135
147
} ;
136
148
137
- StreamWrap . prototype . _enqueue = function enqueue ( req ) {
149
+ function QueueItem ( type , req ) {
150
+ this . type = type ;
151
+ this . req = req ;
152
+ this . prev = this ;
153
+ this . next = this ;
154
+ }
155
+
156
+ StreamWrap . prototype . _enqueue = function enqueue ( type , req ) {
157
+ const item = new QueueItem ( type , req ) ;
138
158
if ( this . _queue === null ) {
139
- this . _queue = req ;
140
- req . _prev = req ;
141
- req . _next = req ;
142
- return ;
159
+ this . _queue = item ;
160
+ return item ;
143
161
}
144
162
145
- req . _next = this . _queue . _next ;
146
- req . _prev = this . _queue ;
147
- req . _next . _prev = req ;
148
- req . _prev . _next = req ;
163
+ item . next = this . _queue . next ;
164
+ item . prev = this . _queue ;
165
+ item . next . prev = item ;
166
+ item . prev . next = item ;
167
+
168
+ return item ;
149
169
} ;
150
170
151
- StreamWrap . prototype . _dequeue = function dequeue ( req ) {
152
- var next = req . _next ;
153
- var prev = req . _prev ;
171
+ StreamWrap . prototype . _dequeue = function dequeue ( item ) {
172
+ var next = item . next ;
173
+ var prev = item . prev ;
154
174
155
175
if ( next === null && prev === null )
156
176
return false ;
157
177
158
- req . _next = null ;
159
- req . _prev = null ;
178
+ item . next = null ;
179
+ item . prev = null ;
160
180
161
- if ( next === req ) {
181
+ if ( next === item ) {
162
182
prev = null ;
163
183
next = null ;
164
184
} else {
165
- prev . _next = next ;
166
- next . _prev = prev ;
185
+ prev . next = next ;
186
+ next . prev = prev ;
167
187
}
168
188
169
- if ( this . _queue === req )
189
+ if ( this . _queue === item )
170
190
this . _queue = next ;
171
191
172
192
return true ;
@@ -178,12 +198,17 @@ StreamWrap.prototype.doClose = function doClose(cb) {
178
198
179
199
setImmediate ( function ( ) {
180
200
while ( self . _queue !== null ) {
181
- const req = self . _queue ;
182
- self . _dequeue ( req ) ;
201
+ const item = self . _queue ;
202
+ const req = item . req ;
203
+ self . _dequeue ( item ) ;
183
204
184
205
const errCode = uv . UV_ECANCELED ;
185
- handle . doAfterWrite ( req ) ;
186
- handle . finishWrite ( req , errCode ) ;
206
+ if ( item . type === 'write' ) {
207
+ handle . doAfterWrite ( req ) ;
208
+ handle . finishWrite ( req , errCode ) ;
209
+ } else if ( item . type === 'shutdown' ) {
210
+ handle . finishShutdown ( req , errCode ) ;
211
+ }
187
212
}
188
213
189
214
// Should be already set by net.js
0 commit comments