Chromium Code Reviews| 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 |