OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 define('data_sender', [ | 5 define('data_sender', [ |
6 'device/serial/data_stream.mojom', | 6 'device/serial/data_stream.mojom', |
7 'device/serial/data_stream_serialization.mojom', | 7 'device/serial/data_stream_serialization.mojom', |
8 'mojo/public/js/core', | 8 'mojo/public/js/core', |
9 'mojo/public/js/router', | 9 'mojo/public/js/router', |
10 ], function(dataStreamMojom, serialization, core, routerModule) { | 10 ], function(dataStreamMojom, serialization, core, routerModule) { |
11 /** | 11 /** |
12 * @module data_sender | 12 * @module data_sender |
13 */ | 13 */ |
14 | 14 |
15 /** | 15 /** |
16 * A pending send operation. | 16 * A pending send operation. |
17 * @param {!ArrayBuffer} data The data to be sent. | 17 * @param {!ArrayBuffer} data The data to be sent. |
18 * @constructor | 18 * @constructor |
19 * @alias module:data_sender~PendingSend | 19 * @alias module:data_sender~PendingSend |
20 * @private | 20 * @private |
21 */ | 21 */ |
22 function PendingSend(data) { | 22 function PendingSend(data) { |
23 /** | 23 /** |
24 * The remaining data to be sent. | 24 * The data to be sent. |
25 * @type {!ArrayBuffer} | 25 * @type {ArrayBuffer} |
26 * @private | 26 * @private |
27 */ | 27 */ |
28 this.data_ = data; | 28 this.data_ = data; |
29 /** | 29 /** |
30 * The total length of data to be sent. | 30 * The total length of data to be sent. |
31 * @type {number} | 31 * @type {number} |
32 * @private | 32 * @private |
33 */ | 33 */ |
34 this.length_ = data.byteLength; | 34 this.length_ = data.byteLength; |
35 /** | 35 /** |
36 * The number of bytes that have been received by the DataSink. | |
37 * @type {number} | |
38 * @private | |
39 */ | |
40 this.bytesReceivedBySink_ = 0; | |
41 /** | |
42 * The promise that will be resolved or rejected when this send completes | 36 * The promise that will be resolved or rejected when this send completes |
43 * or fails, respectively. | 37 * or fails, respectively. |
44 * @type {!Promise.<number>} | 38 * @type {!Promise.<number>} |
45 * @private | 39 * @private |
46 */ | 40 */ |
47 this.promise_ = new Promise(function(resolve, reject) { | 41 this.promise_ = new Promise(function(resolve, reject) { |
48 /** | 42 /** |
49 * The callback to call on success. | 43 * The callback to call on success. |
50 * @type {Function} | 44 * @type {Function} |
51 * @private | 45 * @private |
(...skipping 11 matching lines...) Expand all Loading... |
63 /** | 57 /** |
64 * Returns the promise that will be resolved when this operation completes or | 58 * Returns the promise that will be resolved when this operation completes or |
65 * rejected if an error occurs. | 59 * rejected if an error occurs. |
66 * @return {!Promise.<number>} A promise to the number of bytes sent. | 60 * @return {!Promise.<number>} A promise to the number of bytes sent. |
67 */ | 61 */ |
68 PendingSend.prototype.getPromise = function() { | 62 PendingSend.prototype.getPromise = function() { |
69 return this.promise_; | 63 return this.promise_; |
70 }; | 64 }; |
71 | 65 |
72 /** | 66 /** |
73 * @typedef module:data_sender~PendingSend.ReportBytesResult | |
74 * @property {number} bytesUnreported The number of bytes reported that were | |
75 * not part of the send. | |
76 * @property {boolean} done Whether this send has completed. | |
77 * @property {?number} bytesToFlush The number of bytes to flush in the event | |
78 * of an error. | |
79 */ | |
80 | |
81 /** | |
82 * Invoked when the DataSink reports that bytes have been sent. Resolves the | 67 * Invoked when the DataSink reports that bytes have been sent. Resolves the |
83 * promise returned by | 68 * promise returned by |
84 * [getPromise()]{@link module:data_sender~PendingSend#getPromise} once all | 69 * [getPromise()]{@link module:data_sender~PendingSend#getPromise} once all |
85 * bytes have been reported as sent. | 70 * bytes have been reported as sent. |
86 * @param {number} numBytes The number of bytes sent. | |
87 * @return {!module:data_sender~PendingSend.ReportBytesResult} | |
88 */ | 71 */ |
89 PendingSend.prototype.reportBytesSent = function(numBytes) { | 72 PendingSend.prototype.reportBytesSent = function() { |
90 var result = this.reportBytesSentInternal_(numBytes); | 73 this.successCallback_(this.length_); |
91 if (this.bytesReceivedBySink_ == this.length_) { | |
92 result.done = true; | |
93 this.successCallback_(this.bytesReceivedBySink_); | |
94 } | |
95 return result; | |
96 }; | 74 }; |
97 | 75 |
98 /** | 76 /** |
99 * Invoked when the DataSink reports an error. Rejects the promise returned by | 77 * Invoked when the DataSink reports an error. Rejects the promise returned by |
100 * [getPromise()]{@link module:data_sender~PendingSend#getPromise} unless the | 78 * [getPromise()]{@link module:data_sender~PendingSend#getPromise} unless the |
101 * error occurred after this send, that is, unless numBytes is greater than | 79 * error occurred after this send, that is, unless numBytes is greater than |
102 * the nubmer of outstanding bytes. | 80 * the nubmer of outstanding bytes. |
103 * @param {number} numBytes The number of bytes sent. | 81 * @param {number} numBytes The number of bytes sent. |
104 * @param {number} error The error reported by the DataSink. | 82 * @param {number} error The error reported by the DataSink. |
105 * @return {!module:data_sender~PendingSend.ReportBytesResult} | |
106 */ | 83 */ |
107 PendingSend.prototype.reportBytesSentAndError = function(numBytes, error) { | 84 PendingSend.prototype.reportBytesSentAndError = function(numBytes, error) { |
108 var result = this.reportBytesSentInternal_(numBytes); | |
109 // If there are remaining bytes to report, the error occurred after this | |
110 // PendingSend so we should report success. | |
111 if (result.bytesUnreported > 0) { | |
112 this.successCallback_(this.bytesReceivedBySink_); | |
113 result.bytesToFlush = 0; | |
114 return result; | |
115 } | |
116 | |
117 var e = new Error(); | 85 var e = new Error(); |
118 e.error = error; | 86 e.error = error; |
119 e.bytesSent = this.bytesReceivedBySink_; | 87 e.bytesSent = numBytes; |
120 this.errorCallback_(e); | 88 this.errorCallback_(e); |
121 this.done = true; | |
122 result.bytesToFlush = | |
123 this.length_ - this.data_.byteLength - this.bytesReceivedBySink_; | |
124 return result; | |
125 }; | |
126 | |
127 /** | |
128 * Updates the internal state in response to a report from the DataSink. | |
129 * @param {number} numBytes The number of bytes sent. | |
130 * @return {!module:data_sender~PendingSend.ReportBytesResult} | |
131 * @private | |
132 */ | |
133 PendingSend.prototype.reportBytesSentInternal_ = function(numBytes) { | |
134 this.bytesReceivedBySink_ += numBytes; | |
135 var result = {bytesUnreported: 0}; | |
136 if (this.bytesReceivedBySink_ > this.length_) { | |
137 result.bytesUnreported = this.bytesReceivedBySink_ - this.length_; | |
138 this.bytesReceivedBySink_ = this.length_; | |
139 } | |
140 result.done = false; | |
141 return result; | |
142 }; | 89 }; |
143 | 90 |
144 /** | 91 /** |
145 * Writes pending data into the data pipe. | 92 * Writes pending data into the data pipe. |
146 * @param {!DataSink} sink The DataSink to receive the data. | 93 * @param {!DataSink} sink The DataSink to receive the data. |
147 * @param {number} availableBufferCapacity The maximum number of bytes to | |
148 * send. | |
149 * @return {!Object} result The send result. | 94 * @return {!Object} result The send result. |
150 * @return {boolean} result.completed Whether all of the pending data was | 95 * @return {boolean} result.completed Whether all of the pending data was |
151 * sent. | 96 * sent. |
152 * @return {number} result.remainingBufferCapacity The remaining send buffer | |
153 * capacity. | |
154 */ | 97 */ |
155 PendingSend.prototype.sendData = function(sink, availableBufferCapacity) { | 98 PendingSend.prototype.sendData = function(sink) { |
156 var numBytesToSend = | 99 var dataSent = sink.onData(new Uint8Array(this.data_)); |
157 Math.min(availableBufferCapacity, this.data_.byteLength); | 100 this.data_ = null; |
158 sink.onData(new Uint8Array(this.data_, 0, numBytesToSend)); | 101 return dataSent; |
159 this.data_ = this.data_.slice(numBytesToSend); | |
160 return { | |
161 completed: this.data_.byteLength == 0, | |
162 remainingBufferCapacity: availableBufferCapacity - numBytesToSend, | |
163 }; | |
164 }; | 102 }; |
165 | 103 |
166 /** | 104 /** |
167 * A DataSender that sends data to a DataSink. | 105 * A DataSender that sends data to a DataSink. |
168 * @param {!MojoHandle} handle The handle to the DataSink. | 106 * @param {!MojoHandle} sink The handle to the DataSink. |
169 * @param {number} bufferSize How large a buffer to use for data. | 107 * @param {number} bufferSize How large a buffer to use for data. |
170 * @param {number} fatalErrorValue The send error value to report in the | 108 * @param {number} fatalErrorValue The send error value to report in the |
171 * event of a fatal error. | 109 * event of a fatal error. |
172 * @constructor | 110 * @constructor |
173 * @alias module:data_sender.DataSender | 111 * @alias module:data_sender.DataSender |
174 */ | 112 */ |
175 function DataSender(handle, bufferSize, fatalErrorValue) { | 113 function DataSender(sink, bufferSize, fatalErrorValue) { |
176 this.init_(handle, fatalErrorValue, bufferSize); | 114 this.init_(sink, fatalErrorValue); |
177 this.sink_.init(bufferSize); | |
178 } | 115 } |
179 | 116 |
180 DataSender.prototype = | |
181 $Object.create(dataStreamMojom.DataSinkClient.stubClass.prototype); | |
182 | |
183 /** | 117 /** |
184 * Closes this DataSender. | 118 * Closes this DataSender. |
185 */ | 119 */ |
186 DataSender.prototype.close = function() { | 120 DataSender.prototype.close = function() { |
187 if (this.shutDown_) | 121 if (this.shutDown_) |
188 return; | 122 return; |
189 this.shutDown_ = true; | 123 this.shutDown_ = true; |
190 this.router_.close(); | 124 this.router_.close(); |
191 while (this.pendingSends_.length) { | |
192 this.pendingSends_.pop().reportBytesSentAndError( | |
193 0, this.fatalErrorValue_); | |
194 } | |
195 while (this.sendsAwaitingAck_.length) { | 125 while (this.sendsAwaitingAck_.length) { |
196 this.sendsAwaitingAck_.pop().reportBytesSentAndError( | 126 this.sendsAwaitingAck_.pop().reportBytesSentAndError( |
197 0, this.fatalErrorValue_); | 127 0, this.fatalErrorValue_); |
198 } | 128 } |
199 this.callCancelCallback_(); | 129 this.callCancelCallback_(); |
200 }; | 130 }; |
201 | 131 |
202 /** | 132 /** |
203 * Initialize this DataSender. | 133 * Initialize this DataSender. |
204 * @param {!MojoHandle} sink A handle to the DataSink | 134 * @param {!MojoHandle} sink A handle to the DataSink. |
205 * @param {number} fatalErrorValue The error to dispatch in the event of a | 135 * @param {number} fatalErrorValue The error to dispatch in the event of a |
206 * fatal error. | 136 * fatal error. |
207 * @param {number} bufferSize The size of the send buffer. | |
208 * @private | 137 * @private |
209 */ | 138 */ |
210 DataSender.prototype.init_ = function(sink, fatalErrorValue, bufferSize) { | 139 DataSender.prototype.init_ = function(sink, fatalErrorValue) { |
211 /** | 140 /** |
212 * The error to be dispatched in the event of a fatal error. | 141 * The error to be dispatched in the event of a fatal error. |
213 * @const {number} | 142 * @const {number} |
214 * @private | 143 * @private |
215 */ | 144 */ |
216 this.fatalErrorValue_ = fatalErrorValue; | 145 this.fatalErrorValue_ = fatalErrorValue; |
217 /** | 146 /** |
218 * Whether this DataSender has shut down. | 147 * Whether this DataSender has shut down. |
219 * @type {boolean} | 148 * @type {boolean} |
220 * @private | 149 * @private |
221 */ | 150 */ |
222 this.shutDown_ = false; | 151 this.shutDown_ = false; |
223 /** | 152 /** |
224 * The [Router]{@link module:mojo/public/js/router.Router} for the | 153 * The [Router]{@link module:mojo/public/js/router.Router} for the |
225 * connection to the DataSink. | 154 * connection to the DataSink. |
226 * @private | 155 * @private |
227 */ | 156 */ |
228 this.router_ = new routerModule.Router(sink); | 157 this.router_ = new routerModule.Router(sink); |
229 /** | 158 /** |
230 * The connection to the DataSink. | 159 * The connection to the DataSink. |
231 * @private | 160 * @private |
232 */ | 161 */ |
233 this.sink_ = new dataStreamMojom.DataSink.proxyClass(this.router_); | 162 this.sink_ = new dataStreamMojom.DataSink.proxyClass(this.router_); |
234 this.router_.setIncomingReceiver(this); | |
235 /** | |
236 * A queue of sends that have not fully sent their data to the DataSink. | |
237 * @type {!module:data_sender~PendingSend[]} | |
238 * @private | |
239 */ | |
240 this.pendingSends_ = []; | |
241 /** | 163 /** |
242 * A queue of sends that have sent their data to the DataSink, but have not | 164 * A queue of sends that have sent their data to the DataSink, but have not |
243 * been received by the DataSink. | 165 * been received by the DataSink. |
244 * @type {!module:data_sender~PendingSend[]} | 166 * @type {!module:data_sender~PendingSend[]} |
245 * @private | 167 * @private |
246 */ | 168 */ |
247 this.sendsAwaitingAck_ = []; | 169 this.sendsAwaitingAck_ = []; |
248 | 170 |
249 /** | 171 /** |
250 * The callback that will resolve a pending cancel if one is in progress. | 172 * The callback that will resolve a pending cancel if one is in progress. |
251 * @type {?Function} | 173 * @type {?Function} |
252 * @private | 174 * @private |
253 */ | 175 */ |
254 this.pendingCancel_ = null; | 176 this.pendingCancel_ = null; |
255 | 177 |
256 /** | 178 /** |
257 * The promise that will be resolved when a pending cancel completes if one | 179 * The promise that will be resolved when a pending cancel completes if one |
258 * is in progress. | 180 * is in progress. |
259 * @type {Promise} | 181 * @type {Promise} |
260 * @private | 182 * @private |
261 */ | 183 */ |
262 this.cancelPromise_ = null; | 184 this.cancelPromise_ = null; |
263 /** | |
264 * The available send buffer capacity. | |
265 * @type {number} | |
266 * @private | |
267 */ | |
268 this.availableBufferCapacity_ = bufferSize; | |
269 }; | 185 }; |
270 | 186 |
271 /** | 187 /** |
272 * Serializes this DataSender. | 188 * Serializes this DataSender. |
273 * This will cancel any sends in progress before the returned promise | 189 * This will cancel any sends in progress before the returned promise |
274 * resolves. | 190 * resolves. |
275 * @return {!Promise.<SerializedDataSender>} A promise that will resolve to | 191 * @return {!Promise.<SerializedDataSender>} A promise that will resolve to |
276 * the serialization of this DataSender. If this DataSender has shut down, | 192 * the serialization of this DataSender. If this DataSender has shut down, |
277 * the promise will resolve to null. | 193 * the promise will resolve to null. |
278 */ | 194 */ |
279 DataSender.prototype.serialize = function() { | 195 DataSender.prototype.serialize = function() { |
280 if (this.shutDown_) | 196 if (this.shutDown_) |
281 return Promise.resolve(null); | 197 return Promise.resolve(null); |
282 | 198 |
283 var readyToSerialize = Promise.resolve(); | 199 var readyToSerialize = Promise.resolve(); |
284 if (this.pendingSends_.length || this.sendsAwaitingAck_.length) { | 200 if (this.sendsAwaitingAck_.length) { |
285 if (this.pendingCancel_) | 201 if (this.pendingCancel_) |
286 readyToSerialize = this.cancelPromise_; | 202 readyToSerialize = this.cancelPromise_; |
287 else | 203 else |
288 readyToSerialize = this.cancel(this.fatalErrorValue_); | 204 readyToSerialize = this.cancel(this.fatalErrorValue_); |
289 } | 205 } |
290 return readyToSerialize.then(function() { | 206 return readyToSerialize.then(function() { |
291 var serialized = new serialization.SerializedDataSender(); | 207 var serialized = new serialization.SerializedDataSender(); |
292 serialized.sink = this.router_.connector_.handle_; | 208 serialized.sink = this.router_.connector_.handle_; |
293 serialized.fatal_error_value = this.fatalErrorValue_; | 209 serialized.fatal_error_value = this.fatalErrorValue_; |
294 serialized.buffer_size = this.availableBufferCapacity_; | |
295 this.router_.connector_.handle_ = null; | 210 this.router_.connector_.handle_ = null; |
296 this.router_.close(); | 211 this.router_.close(); |
297 this.shutDown_ = true; | 212 this.shutDown_ = true; |
298 return serialized; | 213 return serialized; |
299 }.bind(this)); | 214 }.bind(this)); |
300 }; | 215 }; |
301 | 216 |
302 /** | 217 /** |
303 * Deserializes a SerializedDataSender. | 218 * Deserializes a SerializedDataSender. |
304 * @param {SerializedDataSender} serialized The serialized DataSender. | 219 * @param {SerializedDataSender} serialized The serialized DataSender. |
305 * @return {!DataSender} The deserialized DataSender. | 220 * @return {!DataSender} The deserialized DataSender. |
306 */ | 221 */ |
307 DataSender.deserialize = function(serialized) { | 222 DataSender.deserialize = function(serialized) { |
308 var sender = $Object.create(DataSender.prototype); | 223 var sender = $Object.create(DataSender.prototype); |
309 sender.deserialize_(serialized); | 224 sender.deserialize_(serialized); |
310 return sender; | 225 return sender; |
311 }; | 226 }; |
312 | 227 |
313 /** | 228 /** |
314 * Deserializes a SerializedDataSender into this DataSender. | 229 * Deserializes a SerializedDataSender into this DataSender. |
315 * @param {SerializedDataSender} serialized The serialized DataSender. | 230 * @param {SerializedDataSender} serialized The serialized DataSender. |
316 * @private | 231 * @private |
317 */ | 232 */ |
318 DataSender.prototype.deserialize_ = function(serialized) { | 233 DataSender.prototype.deserialize_ = function(serialized) { |
319 if (!serialized) { | 234 if (!serialized) { |
320 this.shutDown_ = true; | 235 this.shutDown_ = true; |
321 return; | 236 return; |
322 } | 237 } |
323 this.init_( | 238 this.init_(serialized.sink, serialized.fatal_error_value, |
324 serialized.sink, serialized.fatal_error_value, serialized.buffer_size); | 239 serialized.buffer_size); |
325 }; | 240 }; |
326 | 241 |
327 /** | 242 /** |
328 * Sends data to the DataSink. | 243 * Sends data to the DataSink. |
329 * @return {!Promise.<number>} A promise to the number of bytes sent. If an | 244 * @return {!Promise.<number>} A promise to the number of bytes sent. If an |
330 * error occurs, the promise will reject with an Error object with a | 245 * error occurs, the promise will reject with an Error object with a |
331 * property error containing the error code. | 246 * property error containing the error code. |
332 * @throws Will throw if this has encountered a fatal error or a cancel is in | 247 * @throws Will throw if this has encountered a fatal error or a cancel is in |
333 * progress. | 248 * progress. |
334 */ | 249 */ |
335 DataSender.prototype.send = function(data) { | 250 DataSender.prototype.send = function(data) { |
336 if (this.shutDown_) | 251 if (this.shutDown_) |
337 throw new Error('DataSender has been closed'); | 252 throw new Error('DataSender has been closed'); |
338 if (this.pendingCancel_) | 253 if (this.pendingCancel_) |
339 throw new Error('Cancel in progress'); | 254 throw new Error('Cancel in progress'); |
340 var send = new PendingSend(data); | 255 var send = new PendingSend(data); |
341 this.pendingSends_.push(send); | 256 this.sendsAwaitingAck_.push(send); |
342 this.sendInternal_(); | 257 send.sendData(this.sink_).then(this.reportBytesSentAndError.bind(this)); |
343 return send.getPromise(); | 258 return send.getPromise(); |
344 }; | 259 }; |
345 | 260 |
346 DataSender.prototype.sendInternal_ = function() { | |
347 while (this.pendingSends_.length && this.availableBufferCapacity_) { | |
348 var result = this.pendingSends_[0].sendData( | |
349 this.sink_, this.availableBufferCapacity_); | |
350 this.availableBufferCapacity_ = result.remainingBufferCapacity; | |
351 if (result.completed) { | |
352 this.sendsAwaitingAck_.push(this.pendingSends_.shift()); | |
353 } | |
354 } | |
355 }; | |
356 | |
357 /** | 261 /** |
358 * Requests the cancellation of any in-progress sends. Calls to | 262 * Requests the cancellation of any in-progress sends. Calls to |
359 * [send()]{@link module:data_sender.DataSender#send} will fail until the | 263 * [send()]{@link module:data_sender.DataSender#send} will fail until the |
360 * cancel has completed. | 264 * cancel has completed. |
361 * @param {number} error The error to report for cancelled sends. | 265 * @param {number} error The error to report for cancelled sends. |
362 * @return {!Promise} A promise that will resolve when the cancel completes. | 266 * @return {!Promise} A promise that will resolve when the cancel completes. |
363 * @throws Will throw if this has encountered a fatal error or another cancel | 267 * @throws Will throw if this has encountered a fatal error or another cancel |
364 * is in progress. | 268 * is in progress. |
365 */ | 269 */ |
366 DataSender.prototype.cancel = function(error) { | 270 DataSender.prototype.cancel = function(error) { |
367 if (this.shutDown_) | 271 if (this.shutDown_) |
368 throw new Error('DataSender has been closed'); | 272 throw new Error('DataSender has been closed'); |
369 if (this.pendingCancel_) | 273 if (this.pendingCancel_) |
370 throw new Error('Cancel already in progress'); | 274 throw new Error('Cancel already in progress'); |
371 if (this.pendingSends_.length + this.sendsAwaitingAck_.length == 0) | 275 if (this.sendsAwaitingAck_.length == 0) |
372 return Promise.resolve(); | 276 return Promise.resolve(); |
373 | 277 |
374 this.sink_.cancel(error); | 278 this.sink_.cancel(error); |
375 this.cancelPromise_ = new Promise(function(resolve) { | 279 this.cancelPromise_ = new Promise(function(resolve) { |
376 this.pendingCancel_ = resolve; | 280 this.pendingCancel_ = resolve; |
377 }.bind(this)); | 281 }.bind(this)); |
378 return this.cancelPromise_; | 282 return this.cancelPromise_; |
379 }; | 283 }; |
380 | 284 |
381 /** | 285 /** |
382 * Calls and clears the pending cancel callback if one is pending. | 286 * Calls and clears the pending cancel callback if one is pending. |
383 * @private | 287 * @private |
384 */ | 288 */ |
385 DataSender.prototype.callCancelCallback_ = function() { | 289 DataSender.prototype.callCancelCallback_ = function() { |
386 if (this.pendingCancel_) { | 290 if (this.pendingCancel_) { |
387 this.cancelPromise_ = null; | 291 this.cancelPromise_ = null; |
388 this.pendingCancel_(); | 292 this.pendingCancel_(); |
389 this.pendingCancel_ = null; | 293 this.pendingCancel_ = null; |
390 } | 294 } |
391 }; | 295 }; |
392 | 296 |
393 /** | 297 /** |
394 * Invoked by the DataSink to report that data has been successfully sent. | 298 * Invoked by the DataSink to report that data has been successfully sent. |
395 * @param {number} numBytes The number of bytes sent. | |
396 * @private | 299 * @private |
397 */ | 300 */ |
398 DataSender.prototype.reportBytesSent = function(numBytes) { | 301 DataSender.prototype.reportBytesSent = function() { |
399 this.availableBufferCapacity_ += numBytes; | 302 var result = this.sendsAwaitingAck_[0].reportBytesSent(); |
400 while (numBytes > 0 && this.sendsAwaitingAck_.length) { | 303 this.sendsAwaitingAck_.shift(); |
401 var result = this.sendsAwaitingAck_[0].reportBytesSent(numBytes); | 304 |
402 numBytes = result.bytesUnreported; | |
403 if (result.done) | |
404 this.sendsAwaitingAck_.shift(); | |
405 } | |
406 if (numBytes > 0 && this.pendingSends_.length) { | |
407 var result = this.pendingSends_[0].reportBytesSent(numBytes); | |
408 numBytes = result.bytesUnreported; | |
409 } | |
410 // A cancel is completed when all of the sends that were in progress have | 305 // A cancel is completed when all of the sends that were in progress have |
411 // completed or failed. This is the case where all sends complete | 306 // completed or failed. This is the case where all sends complete |
412 // successfully. | 307 // successfully. |
413 if (this.pendingSends_.length + this.sendsAwaitingAck_.length == 0) | 308 if (this.sendsAwaitingAck_.length == 0) |
414 this.callCancelCallback_(); | 309 this.callCancelCallback_(); |
415 | |
416 this.sendInternal_(); | |
417 }; | 310 }; |
418 | 311 |
419 /** | 312 /** |
420 * Invoked by the DataSink to report an error in sending data. | 313 * Invoked by the DataSink to report an error in sending data. |
421 * @param {number} numBytes The number of bytes sent. | 314 * @param {number} numBytes The number of bytes sent. |
422 * @param {number} error The error reported by the DataSink. | 315 * @param {number} error The error reported by the DataSink. |
423 * @private | 316 * @private |
424 */ | 317 */ |
425 DataSender.prototype.reportBytesSentAndError = function(numBytes, error) { | 318 DataSender.prototype.reportBytesSentAndError = function(result) { |
426 this.availableBufferCapacity_ += numBytes; | 319 var numBytes = result.bytes_sent; |
427 while (this.sendsAwaitingAck_.length) { | 320 var error = result.error; |
428 var result = this.sendsAwaitingAck_[0].reportBytesSentAndError( | 321 if (!error) { |
429 numBytes, error); | 322 this.reportBytesSent(); |
430 numBytes = result.bytesUnreported; | 323 return; |
431 this.sendsAwaitingAck_.shift(); | |
432 this.availableBufferCapacity_ += result.bytesToFlush; | |
433 } | 324 } |
434 while (this.pendingSends_.length) { | 325 var result = |
435 var result = this.pendingSends_[0].reportBytesSentAndError( | 326 this.sendsAwaitingAck_[0].reportBytesSentAndError(numBytes, error); |
436 numBytes, error); | 327 this.sendsAwaitingAck_.shift(); |
437 numBytes = result.bytesUnreported; | 328 if (this.sendsAwaitingAck_.length) |
438 this.pendingSends_.shift(); | 329 return; |
439 // Note: Only the first PendingSend in |pendingSends_| will have data to | |
440 // flush as only the first can have sent data to the DataSink. | |
441 this.availableBufferCapacity_ += result.bytesToFlush; | |
442 } | |
443 this.callCancelCallback_(); | 330 this.callCancelCallback_(); |
444 return Promise.resolve(); | 331 this.sink_.clearError(); |
445 }; | 332 }; |
446 | 333 |
447 return {DataSender: DataSender}; | 334 return {DataSender: DataSender}; |
448 }); | 335 }); |
OLD | NEW |