| 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..d750ed2f51bcbb648f2a85ac26c59b2da8ba92cb 100644
|
| --- a/extensions/renderer/resources/data_sender.js
|
| +++ b/extensions/renderer/resources/data_sender.js
|
| @@ -5,9 +5,10 @@
|
| 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
|
| */
|
| @@ -170,30 +171,55 @@ 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}
|
| @@ -201,6 +227,24 @@ define('data_sender', [
|
| */
|
| this.fatalErrorValue_ = fatalErrorValue;
|
| /**
|
| + * Whether this DataReceiver 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
|
| @@ -222,45 +266,78 @@ define('data_sender', [
|
| * @private
|
| */
|
| this.sendsAwaitingAck_ = [];
|
| +
|
| /**
|
| * The callback that will resolve a pending cancel if one is in progress.
|
| * @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);
|
| };
|
|
|
| /**
|
| @@ -301,9 +378,10 @@ 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_;
|
| };
|
|
|
| /**
|
| @@ -337,6 +415,7 @@ define('data_sender', [
|
| */
|
| DataSender.prototype.callCancelCallback_ = function() {
|
| if (this.pendingCancel_) {
|
| + this.cancelPromise_ = null;
|
| this.pendingCancel_();
|
| this.pendingCancel_ = null;
|
| }
|
|
|