| Index: extensions/renderer/resources/data_sender.js
|
| diff --git a/extensions/renderer/resources/data_sender.js b/extensions/renderer/resources/data_sender.js
|
| index ee1abb33ab0b98d29639f21c8ae9098e500d2a24..b95cd0be7969d58130bb877c94d169c08403b3bb 100644
|
| --- a/extensions/renderer/resources/data_sender.js
|
| +++ b/extensions/renderer/resources/data_sender.js
|
| @@ -5,16 +5,17 @@
|
| define('data_sender', [
|
| 'async_waiter',
|
| 'device/serial/data_stream.mojom',
|
| + 'device/serial/data_stream_serialization.mojom',
|
| 'mojo/public/js/bindings/core',
|
| 'mojo/public/js/bindings/router',
|
| -], function(asyncWaiter, dataStreamMojom, core, routerModule) {
|
| +], function(asyncWaiter, dataStreamMojom, serialization, core, routerModule) {
|
| /**
|
| * @module data_sender
|
| */
|
|
|
| /**
|
| * A pending send operation.
|
| - * @param {ArrayBuffer} data The data to be sent.
|
| + * @param {!ArrayBuffer} data The data to be sent.
|
| * @constructor
|
| * @alias module:data_sender~PendingSend
|
| * @private
|
| @@ -22,7 +23,7 @@ define('data_sender', [
|
| function PendingSend(data) {
|
| /**
|
| * The remaining data to be sent.
|
| - * @type {ArrayBuffer}
|
| + * @type {!ArrayBuffer}
|
| * @private
|
| */
|
| this.data_ = data;
|
| @@ -41,7 +42,7 @@ define('data_sender', [
|
| /**
|
| * The promise that will be resolved or rejected when this send completes
|
| * or fails, respectively.
|
| - * @type {Promise.<number>}
|
| + * @type {!Promise.<number>}
|
| * @private
|
| */
|
| this.promise_ = new Promise(function(resolve, reject) {
|
| @@ -63,7 +64,7 @@ define('data_sender', [
|
| /**
|
| * Returns the promise that will be resolved when this operation completes or
|
| * rejected if an error occurs.
|
| - * @return {Promise.<number>} A promise to the number of bytes sent.
|
| + * @return {!Promise.<number>} A promise to the number of bytes sent.
|
| */
|
| PendingSend.prototype.getPromise = function() {
|
| return this.promise_;
|
| @@ -73,8 +74,8 @@ define('data_sender', [
|
| * @typedef module:data_sender~PendingSend.ReportBytesResult
|
| * @property {number} bytesUnreported The number of bytes reported that were
|
| * not part of the send.
|
| - * @property {boolean?} done Whether this send has completed.
|
| - * @property {number?} bytesToFlush The number of bytes to flush in the event
|
| + * @property {boolean} done Whether this send has completed.
|
| + * @property {?number} bytesToFlush The number of bytes to flush in the event
|
| * of an error.
|
| */
|
|
|
| @@ -84,7 +85,7 @@ define('data_sender', [
|
| * [getPromise()]{@link module:data_sender~PendingSend#getPromise} once all
|
| * bytes have been reported as sent.
|
| * @param {number} numBytes The number of bytes sent.
|
| - * @return {module:data_sender~PendingSend.ReportBytesResult}
|
| + * @return {!module:data_sender~PendingSend.ReportBytesResult}
|
| */
|
| PendingSend.prototype.reportBytesSent = function(numBytes) {
|
| var result = this.reportBytesSentInternal_(numBytes);
|
| @@ -102,7 +103,7 @@ define('data_sender', [
|
| * the nubmer of outstanding bytes.
|
| * @param {number} numBytes The number of bytes sent.
|
| * @param {number} error The error reported by the DataSink.
|
| - * @return {module:data_sender~PendingSend.ReportBytesResult}
|
| + * @return {!module:data_sender~PendingSend.ReportBytesResult}
|
| */
|
| PendingSend.prototype.reportBytesSentAndError = function(numBytes, error) {
|
| var result = this.reportBytesSentInternal_(numBytes);
|
| @@ -127,7 +128,7 @@ define('data_sender', [
|
| /**
|
| * Updates the internal state in response to a report from the DataSink.
|
| * @param {number} numBytes The number of bytes sent.
|
| - * @return {module:data_sender~PendingSend.ReportBytesResult}
|
| + * @return {!module:data_sender~PendingSend.ReportBytesResult}
|
| * @private
|
| */
|
| PendingSend.prototype.reportBytesSentInternal_ = function(numBytes) {
|
| @@ -143,7 +144,7 @@ define('data_sender', [
|
|
|
| /**
|
| * Writes pending data into the data pipe.
|
| - * @param {MojoHandle} handle The handle to the data pipe.
|
| + * @param {!MojoHandle} handle The handle to the data pipe.
|
| * @return {number} The Mojo result corresponding to the outcome:
|
| * <ul>
|
| * <li>RESULT_OK if the write completes successfully;
|
| @@ -162,7 +163,7 @@ define('data_sender', [
|
|
|
| /**
|
| * A DataSender that sends data to a DataSink.
|
| - * @param {MojoHandle} handle The handle to the DataSink.
|
| + * @param {!MojoHandle} handle The handle to the DataSink.
|
| * @param {number} bufferSize How large a buffer the data pipe should use.
|
| * @param {number} fatalErrorValue The send error value to report in the
|
| * event of a fatal error.
|
| @@ -170,40 +171,83 @@ define('data_sender', [
|
| * @alias module:data_sender.DataSender
|
| */
|
| function DataSender(handle, bufferSize, fatalErrorValue) {
|
| - /**
|
| - * The [Router]{@link module:mojo/public/js/bindings/router.Router} for the
|
| - * connection to the DataSink.
|
| - * @private
|
| - */
|
| - this.router_ = new routerModule.Router(handle);
|
| - /**
|
| - * The connection to the DataSink.
|
| - * @private
|
| - */
|
| - this.sink_ = new dataStreamMojom.DataSinkProxy(this.router_);
|
| - this.router_.setIncomingReceiver(this);
|
| var dataPipeOptions = {
|
| flags: core.CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
|
| elementNumBytes: 1,
|
| capacityNumBytes: bufferSize,
|
| };
|
| var sendPipe = core.createDataPipe(dataPipeOptions);
|
| + this.init_(handle, sendPipe.producerHandle, fatalErrorValue);
|
| this.sink_.init(sendPipe.consumerHandle);
|
| + }
|
| +
|
| + DataSender.prototype =
|
| + $Object.create(dataStreamMojom.DataSinkClientStub.prototype);
|
| +
|
| + /**
|
| + * Closes this DataSender.
|
| + */
|
| + DataSender.prototype.close = function() {
|
| + if (this.shutDown_)
|
| + return;
|
| + this.shutDown_ = true;
|
| + this.waiter_.stop();
|
| + this.router_.close();
|
| + core.close(this.sendPipe_);
|
| + while (this.pendingSends_.length) {
|
| + this.pendingSends_.pop().reportBytesSentAndError(
|
| + 0, this.fatalErrorValue_);
|
| + }
|
| + while (this.sendsAwaitingAck_.length) {
|
| + this.sendsAwaitingAck_.pop().reportBytesSentAndError(
|
| + 0, this.fatalErrorValue_);
|
| + }
|
| + this.callCancelCallback_();
|
| + };
|
| +
|
| + /**
|
| + * Initialize this DataSender.
|
| + * @param {!MojoHandle} sink A handle to the DataSink
|
| + * @param {!MojoHandle} dataPipe A handle to use for sending data to the
|
| + * DataSink.
|
| + * @param {number} fatalErrorValue The error to dispatch in the event of a
|
| + * fatal error.
|
| + * @private
|
| + */
|
| + DataSender.prototype.init_ = function(sink, dataPipe, fatalErrorValue) {
|
| /**
|
| * The handle to the data pipe to use for sending data.
|
| * @private
|
| */
|
| - this.sendPipe_ = sendPipe.producerHandle;
|
| + this.sendPipe_ = dataPipe;
|
| /**
|
| * The error to be dispatched in the event of a fatal error.
|
| - * @type {number}
|
| + * @const {number}
|
| * @private
|
| */
|
| this.fatalErrorValue_ = fatalErrorValue;
|
| /**
|
| + * Whether this DataSender has shut down.
|
| + * @type {boolean}
|
| + * @private
|
| + */
|
| + this.shutDown_ = false;
|
| + /**
|
| + * The [Router]{@link module:mojo/public/js/bindings/router.Router} for the
|
| + * connection to the DataSink.
|
| + * @private
|
| + */
|
| + this.router_ = new routerModule.Router(sink);
|
| + /**
|
| + * The connection to the DataSink.
|
| + * @private
|
| + */
|
| + this.sink_ = new dataStreamMojom.DataSinkProxy(this.router_);
|
| + this.router_.setIncomingReceiver(this);
|
| + /**
|
| * The async waiter used to wait for
|
| * {@link module:data_sender.DataSender#sendPipe_} to be writable.
|
| - * @type module:async_waiter.AsyncWaiter
|
| + * @type {!module:async_waiter.AsyncWaiter}
|
| * @private
|
| */
|
| this.waiter_ = new asyncWaiter.AsyncWaiter(
|
| @@ -211,61 +255,94 @@ define('data_sender', [
|
| this.onHandleReady_.bind(this));
|
| /**
|
| * A queue of sends that have not fully written their data to the data pipe.
|
| - * @type module:data_sender~PendingSend[]
|
| + * @type {!module:data_sender~PendingSend[]}
|
| * @private
|
| */
|
| this.pendingSends_ = [];
|
| /**
|
| * A queue of sends that have written their data to the data pipe, but have
|
| * not been received by the DataSink.
|
| - * @type module:data_sender~PendingSend[]
|
| + * @type {!module:data_sender~PendingSend[]}
|
| * @private
|
| */
|
| this.sendsAwaitingAck_ = [];
|
| +
|
| /**
|
| * The callback that will resolve a pending cancel if one is in progress.
|
| - * @type Function
|
| + * @type {?Function}
|
| * @private
|
| */
|
| this.pendingCancel_ = null;
|
| +
|
| /**
|
| - * Whether this DataReceiver has shut down.
|
| - * @type {boolean}
|
| + * The promise that will be resolved when a pending cancel completes if one
|
| + * is in progress.
|
| + * @type {Promise}
|
| * @private
|
| */
|
| - this.shutDown_ = false;
|
| - }
|
| -
|
| - DataSender.prototype =
|
| - $Object.create(dataStreamMojom.DataSinkClientStub.prototype);
|
| + this.cancelPromise_ = null;
|
| + };
|
|
|
| /**
|
| - * Closes this DataSender.
|
| + * Serializes this DataSender.
|
| + * This will cancel any sends in progress before the returned promise
|
| + * resolves.
|
| + * @return {!Promise.<SerializedDataSender>} A promise that will resolve to
|
| + * the serialization of this DataSender. If this DataSender has shut down,
|
| + * the promise will resolve to null.
|
| */
|
| - DataSender.prototype.close = function() {
|
| + DataSender.prototype.serialize = function() {
|
| if (this.shutDown_)
|
| - return;
|
| - this.shutDown_ = true;
|
| - this.waiter_.stop();
|
| - this.router_.close();
|
| - core.close(this.sendPipe_);
|
| - while (this.pendingSends_.length) {
|
| - this.pendingSends_.pop().reportBytesSentAndError(
|
| - 0, this.fatalErrorValue_);
|
| - }
|
| - while (this.sendsAwaitingAck_.length) {
|
| - this.sendsAwaitingAck_.pop().reportBytesSentAndError(
|
| - 0, this.fatalErrorValue_);
|
| + return Promise.resolve(null);
|
| +
|
| + var readyToSerialize = Promise.resolve();
|
| + if (this.pendingSends_.length) {
|
| + if (this.pendingCancel_)
|
| + readyToSerialize = this.cancelPromise_;
|
| + else
|
| + readyToSerialize = this.cancel(this.fatalErrorValue_);
|
| }
|
| - if (this.pendingCancel_) {
|
| - this.pendingCancel_();
|
| - this.pendingCancel_ = null;
|
| + return readyToSerialize.then(function() {
|
| + this.waiter_.stop();
|
| + var serialized = new serialization.SerializedDataSender();
|
| + serialized.sink = this.router_.connector_.handle_,
|
| + serialized.data_pipe = this.sendPipe_,
|
| + serialized.fatal_error_value = this.fatalErrorValue_,
|
| + this.router_.connector_.handle_ = null;
|
| + this.router_.close();
|
| + this.shutDown_ = true;
|
| + return serialized;
|
| + }.bind(this));
|
| + };
|
| +
|
| + /**
|
| + * Deserializes a SerializedDataSender.
|
| + * @param {SerializedDataSender} serialized The serialized DataSender.
|
| + * @return {!DataSender} The deserialized DataSender.
|
| + */
|
| + DataSender.deserialize = function(serialized) {
|
| + var sender = $Object.create(DataSender.prototype);
|
| + sender.deserialize_(serialized);
|
| + return sender;
|
| + };
|
| +
|
| + /**
|
| + * Deserializes a SerializedDataSender into this DataSender.
|
| + * @param {SerializedDataSender} serialized The serialized DataSender.
|
| + * @private
|
| + */
|
| + DataSender.prototype.deserialize_ = function(serialized) {
|
| + if (!serialized) {
|
| + this.shutDown_ = true;
|
| + return;
|
| }
|
| + this.init_(
|
| + serialized.sink, serialized.data_pipe, serialized.fatal_error_value);
|
| };
|
|
|
| /**
|
| * Sends data to the DataSink.
|
| - * @return {Promise.<number>} A promise to the number of bytes sent. If an
|
| + * @return {!Promise.<number>} A promise to the number of bytes sent. If an
|
| * error occurs, the promise will reject with an Error object with a
|
| * property error containing the error code.
|
| * @throws Will throw if this has encountered a fatal error or a cancel is in
|
| @@ -288,7 +365,7 @@ define('data_sender', [
|
| * [send()]{@link module:data_sender.DataSender#send} will fail until the
|
| * cancel has completed.
|
| * @param {number} error The error to report for cancelled sends.
|
| - * @return {Promise} A promise that will resolve when the cancel completes.
|
| + * @return {!Promise} A promise that will resolve when the cancel completes.
|
| * @throws Will throw if this has encountered a fatal error or another cancel
|
| * is in progress.
|
| */
|
| @@ -301,14 +378,16 @@ define('data_sender', [
|
| return Promise.resolve();
|
|
|
| this.sink_.cancel(error);
|
| - return new Promise(function(resolve) {
|
| + this.cancelPromise_ = new Promise(function(resolve) {
|
| this.pendingCancel_ = resolve;
|
| }.bind(this));
|
| + return this.cancelPromise_;
|
| };
|
|
|
| /**
|
| - * Invoked when |handle_| is ready to write. Writes to the data pipe if the
|
| - * wait is successful.
|
| + * Invoked when
|
| + * |[sendPipe_]{@link module:data_sender.DataSender#sendPipe_}| is ready to
|
| + * write. Writes to the data pipe if the wait is successful.
|
| * @param {number} waitResult The result of the asynchronous wait.
|
| * @private
|
| */
|
| @@ -337,6 +416,7 @@ define('data_sender', [
|
| */
|
| DataSender.prototype.callCancelCallback_ = function() {
|
| if (this.pendingCancel_) {
|
| + this.cancelPromise_ = null;
|
| this.pendingCancel_();
|
| this.pendingCancel_ = null;
|
| }
|
|
|