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 'async_waiter', | 6 'async_waiter', |
7 'device/serial/data_stream.mojom', | 7 'device/serial/data_stream.mojom', |
8 'device/serial/data_stream_serialization.mojom', | |
8 'mojo/public/js/bindings/core', | 9 'mojo/public/js/bindings/core', |
9 'mojo/public/js/bindings/router', | 10 'mojo/public/js/bindings/router', |
10 ], function(asyncWaiter, dataStreamMojom, core, routerModule) { | 11 ], function(asyncWaiter, dataStreamMojom, serialization, core, routerModule) { |
11 /** | 12 /** |
12 * @module data_sender | 13 * @module data_sender |
13 */ | 14 */ |
14 | 15 |
15 /** | 16 /** |
16 * A pending send operation. | 17 * A pending send operation. |
17 * @param {ArrayBuffer} data The data to be sent. | 18 * @param {ArrayBuffer} data The data to be sent. |
18 * @constructor | 19 * @constructor |
19 * @alias module:data_sender~PendingSend | 20 * @alias module:data_sender~PendingSend |
20 * @private | 21 * @private |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
250 this.router_.close(); | 251 this.router_.close(); |
251 core.close(this.sendPipe_); | 252 core.close(this.sendPipe_); |
252 while (this.pendingSends_.length) { | 253 while (this.pendingSends_.length) { |
253 this.pendingSends_.pop().reportBytesSentAndError( | 254 this.pendingSends_.pop().reportBytesSentAndError( |
254 0, this.fatalErrorValue_); | 255 0, this.fatalErrorValue_); |
255 } | 256 } |
256 while (this.sendsAwaitingAck_.length) { | 257 while (this.sendsAwaitingAck_.length) { |
257 this.sendsAwaitingAck_.pop().reportBytesSentAndError( | 258 this.sendsAwaitingAck_.pop().reportBytesSentAndError( |
258 0, this.fatalErrorValue_); | 259 0, this.fatalErrorValue_); |
259 } | 260 } |
260 if (this.pendingCancel_) { | 261 this.callCancelCallback_(); |
261 this.pendingCancel_(); | |
262 this.pendingCancel_ = null; | |
263 } | |
264 }; | 262 }; |
265 | 263 |
266 /** | 264 /** |
265 * Serializes this DataSender. | |
266 * @return {Promise.<?SerializedDataSender>} The serialization of this | |
raymes
2014/09/18 03:16:06
returns a promise that resolves to
Sam McNally
2014/09/19 04:58:46
Done.
| |
267 * DataSender. If this DataSender has shut down, this will return null. | |
raymes
2014/09/18 03:16:06
It's probably worth noting that any sends in progr
Sam McNally
2014/09/19 04:58:47
Done.
| |
268 */ | |
269 DataSender.prototype.serialize = function() { | |
270 if (this.shutDown_) | |
271 return Promise.resolve(null); | |
272 | |
273 var readyToSerialize = Promise.resolve(); | |
274 if (this.pendingSends_.length) { | |
275 if (this.pendingCancel_) | |
276 readyToSerialize = this.cancelPromise_; | |
277 else | |
278 readyToSerialize = this.cancel(this.fatalErrorValue_); | |
279 } | |
280 return readyToSerialize.then(function() { | |
281 this.waiter_.stop(); | |
282 var serialized = new serialization.SerializedDataSender(); | |
283 serialized.sink = this.router_.connector_.handle_, | |
284 serialized.data_pipe = this.sendPipe_, | |
285 serialized.fatal_error_value = this.fatalErrorValue_, | |
286 this.router_.connector_.handle_ = null; | |
287 this.router_.close(); | |
288 this.shutDown_ = true; | |
289 return serialized; | |
290 }.bind(this)); | |
291 }; | |
292 | |
293 /** | |
294 * Deserializes a SerializedDataSender. | |
295 * @param {?SerializedDataSender} serialized The serialized DataSender. | |
296 * @return {DataSender} The deserialized DataSender. | |
297 */ | |
298 DataSender.deserialize = function(serialized) { | |
299 var sender = $Object.create(DataSender.prototype); | |
300 sender.deserialize_(serialized); | |
301 return sender; | |
302 }; | |
303 | |
304 /** | |
305 * Deserializes a SerializedDataSender into this DataSender. | |
306 * @param {?SerializedDataSender} serialized The serialized DataSender. | |
307 * @private | |
308 */ | |
309 DataSender.prototype.deserialize_ = function(serialized) { | |
310 if (!serialized) { | |
311 this.shutDown_ = true; | |
312 return; | |
313 } | |
314 this.sendPipe_ = serialized.data_pipe; | |
315 this.fatalErrorValue_ = serialized.fatal_error_value; | |
316 this.shutDown_ = false; | |
317 this.router_ = new routerModule.Router(serialized.sink); | |
318 this.sink_ = new dataStreamMojom.DataSinkProxy(this.router_); | |
319 this.router_.setIncomingReceiver(this); | |
320 this.waiter_ = new asyncWaiter.AsyncWaiter(this.sendPipe_, | |
321 core.HANDLE_SIGNAL_WRITABLE, | |
322 this.onHandleReady_.bind(this)); | |
323 this.pendingSends_ = []; | |
324 this.sendsAwaitingAck_ = []; | |
raymes
2014/09/18 03:16:06
One downside of this approach (not calling the con
Sam McNally
2014/09/19 04:58:47
Done.
| |
325 }; | |
326 | |
327 /** | |
267 * Sends data to the DataSink. | 328 * Sends data to the DataSink. |
268 * @return {Promise.<number>} A promise to the number of bytes sent. If an | 329 * @return {Promise.<number>} A promise to the number of bytes sent. If an |
269 * error occurs, the promise will reject with an Error object with a | 330 * error occurs, the promise will reject with an Error object with a |
270 * property error containing the error code. | 331 * property error containing the error code. |
271 * @throws Will throw if this has encountered a fatal error or a cancel is in | 332 * @throws Will throw if this has encountered a fatal error or a cancel is in |
272 * progress. | 333 * progress. |
273 */ | 334 */ |
274 DataSender.prototype.send = function(data) { | 335 DataSender.prototype.send = function(data) { |
275 if (this.shutDown_) | 336 if (this.shutDown_) |
276 throw new Error('DataSender has been closed'); | 337 throw new Error('DataSender has been closed'); |
(...skipping 17 matching lines...) Expand all Loading... | |
294 */ | 355 */ |
295 DataSender.prototype.cancel = function(error) { | 356 DataSender.prototype.cancel = function(error) { |
296 if (this.shutDown_) | 357 if (this.shutDown_) |
297 throw new Error('DataSender has been closed'); | 358 throw new Error('DataSender has been closed'); |
298 if (this.pendingCancel_) | 359 if (this.pendingCancel_) |
299 throw new Error('Cancel already in progress'); | 360 throw new Error('Cancel already in progress'); |
300 if (this.pendingSends_.length + this.sendsAwaitingAck_.length == 0) | 361 if (this.pendingSends_.length + this.sendsAwaitingAck_.length == 0) |
301 return Promise.resolve(); | 362 return Promise.resolve(); |
302 | 363 |
303 this.sink_.cancel(error); | 364 this.sink_.cancel(error); |
304 return new Promise(function(resolve) { | 365 this.cancelPromise_ = new Promise(function(resolve) { |
305 this.pendingCancel_ = resolve; | 366 this.pendingCancel_ = resolve; |
306 }.bind(this)); | 367 }.bind(this)); |
368 return this.cancelPromise_; | |
raymes
2014/09/18 03:16:06
so it's safe to have multiple things call .then()
Sam McNally
2014/09/19 04:58:47
Yes!
| |
307 }; | 369 }; |
308 | 370 |
309 /** | 371 /** |
310 * Invoked when |handle_| is ready to write. Writes to the data pipe if the | 372 * Invoked when |handle_| is ready to write. Writes to the data pipe if the |
311 * wait is successful. | 373 * wait is successful. |
312 * @param {number} waitResult The result of the asynchronous wait. | 374 * @param {number} waitResult The result of the asynchronous wait. |
313 * @private | 375 * @private |
314 */ | 376 */ |
315 DataSender.prototype.onHandleReady_ = function(result) { | 377 DataSender.prototype.onHandleReady_ = function(result) { |
316 if (result != core.RESULT_OK) { | 378 if (result != core.RESULT_OK) { |
(...skipping 13 matching lines...) Expand all Loading... | |
330 } | 392 } |
331 } | 393 } |
332 }; | 394 }; |
333 | 395 |
334 /** | 396 /** |
335 * Calls and clears the pending cancel callback if one is pending. | 397 * Calls and clears the pending cancel callback if one is pending. |
336 * @private | 398 * @private |
337 */ | 399 */ |
338 DataSender.prototype.callCancelCallback_ = function() { | 400 DataSender.prototype.callCancelCallback_ = function() { |
339 if (this.pendingCancel_) { | 401 if (this.pendingCancel_) { |
402 this.cancelPromise_ = null; | |
340 this.pendingCancel_(); | 403 this.pendingCancel_(); |
341 this.pendingCancel_ = null; | 404 this.pendingCancel_ = null; |
342 } | 405 } |
343 }; | 406 }; |
344 | 407 |
345 /** | 408 /** |
346 * Invoked by the DataSink to report that data has been successfully sent. | 409 * Invoked by the DataSink to report that data has been successfully sent. |
347 * @param {number} numBytes The number of bytes sent. | 410 * @param {number} numBytes The number of bytes sent. |
348 * @private | 411 * @private |
349 */ | 412 */ |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
388 // Note: Only the first PendingSend in |pendingSends_| will have data to | 451 // Note: Only the first PendingSend in |pendingSends_| will have data to |
389 // flush as only the first can have written data to the data pipe. | 452 // flush as only the first can have written data to the data pipe. |
390 bytesToFlush += result.bytesToFlush; | 453 bytesToFlush += result.bytesToFlush; |
391 } | 454 } |
392 this.callCancelCallback_(); | 455 this.callCancelCallback_(); |
393 return Promise.resolve({bytes_to_flush: bytesToFlush}); | 456 return Promise.resolve({bytes_to_flush: bytesToFlush}); |
394 }; | 457 }; |
395 | 458 |
396 return {DataSender: DataSender}; | 459 return {DataSender: DataSender}; |
397 }); | 460 }); |
OLD | NEW |