mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-12 09:01:16 +00:00
9e8c15b15c
MozReview-Commit-ID: FgTVee7NLyC --HG-- rename : devtools/shared/transport/transport.js => devtools/shared/transport/child-transport.js extra : rebase_source : a077c10f7a9ed0c8688db2f06bf10ab538f37c8a
129 lines
3.8 KiB
JavaScript
129 lines
3.8 KiB
JavaScript
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
"use strict";
|
|
|
|
const { Cr } = require("chrome");
|
|
const flags = require("devtools/shared/flags");
|
|
|
|
/**
|
|
* A transport for the debugging protocol that uses nsIMessageManagers to
|
|
* exchange packets with servers running in child processes.
|
|
*
|
|
* In the parent process, |mm| should be the nsIMessageSender for the
|
|
* child process. In a child process, |mm| should be the child process
|
|
* message manager, which sends packets to the parent.
|
|
*
|
|
* |prefix| is a string included in the message names, to distinguish
|
|
* multiple servers running in the same child process.
|
|
*
|
|
* This transport exchanges messages named 'debug:<prefix>:packet', where
|
|
* <prefix> is |prefix|, whose data is the protocol packet.
|
|
*/
|
|
function ChildDebuggerTransport(mm, prefix) {
|
|
this._mm = mm;
|
|
this._messageName = "debug:" + prefix + ":packet";
|
|
}
|
|
|
|
/*
|
|
* To avoid confusion, we use 'message' to mean something that
|
|
* nsIMessageSender conveys, and 'packet' to mean a remote debugging
|
|
* protocol packet.
|
|
*/
|
|
ChildDebuggerTransport.prototype = {
|
|
constructor: ChildDebuggerTransport,
|
|
|
|
hooks: null,
|
|
|
|
_addListener() {
|
|
this._mm.addMessageListener(this._messageName, this);
|
|
},
|
|
|
|
_removeListener() {
|
|
try {
|
|
this._mm.removeMessageListener(this._messageName, this);
|
|
} catch (e) {
|
|
if (e.result != Cr.NS_ERROR_NULL_POINTER) {
|
|
throw e;
|
|
}
|
|
// In some cases, especially when using messageManagers in non-e10s mode, we reach
|
|
// this point with a dead messageManager which only throws errors but does not
|
|
// seem to indicate in any other way that it is dead.
|
|
}
|
|
},
|
|
|
|
ready: function() {
|
|
this._addListener();
|
|
},
|
|
|
|
close: function() {
|
|
this._removeListener();
|
|
this.hooks.onClosed();
|
|
},
|
|
|
|
receiveMessage: function({data}) {
|
|
this.hooks.onPacket(data);
|
|
},
|
|
|
|
/**
|
|
* Helper method to ensure a given `object` can be sent across message manager
|
|
* without being serialized to JSON.
|
|
* See https://searchfox.org/mozilla-central/rev/6bfadf95b4a6aaa8bb3b2a166d6c3545983e179a/dom/base/nsFrameMessageManager.cpp#458-469
|
|
*/
|
|
_canBeSerialized: function(object) {
|
|
try {
|
|
const holder = new StructuredCloneHolder(object);
|
|
holder.deserialize(this);
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
return true;
|
|
},
|
|
|
|
pathToUnserializable: function(object) {
|
|
for (const key in object) {
|
|
const value = object[key];
|
|
if (!this._canBeSerialized(value)) {
|
|
if (typeof value == "object") {
|
|
return [key].concat(this.pathToUnserializable(value));
|
|
}
|
|
return [key];
|
|
}
|
|
}
|
|
return [];
|
|
},
|
|
|
|
send: function(packet) {
|
|
if (flags.testing && !this._canBeSerialized(packet)) {
|
|
const attributes = this.pathToUnserializable(packet);
|
|
let msg = "Following packet can't be serialized: " + JSON.stringify(packet);
|
|
msg += "\nBecause of attributes: " + attributes.join(", ") + "\n";
|
|
msg += "Did you pass a function or an XPCOM object in it?";
|
|
throw new Error(msg);
|
|
}
|
|
try {
|
|
this._mm.sendAsyncMessage(this._messageName, packet);
|
|
} catch (e) {
|
|
if (e.result != Cr.NS_ERROR_NULL_POINTER) {
|
|
throw e;
|
|
}
|
|
// In some cases, especially when using messageManagers in non-e10s mode, we reach
|
|
// this point with a dead messageManager which only throws errors but does not
|
|
// seem to indicate in any other way that it is dead.
|
|
}
|
|
},
|
|
|
|
startBulkSend: function() {
|
|
throw new Error("Can't send bulk data to child processes.");
|
|
},
|
|
|
|
swapBrowser(mm) {
|
|
this._removeListener();
|
|
this._mm = mm;
|
|
this._addListener();
|
|
},
|
|
};
|
|
|
|
exports.ChildDebuggerTransport = ChildDebuggerTransport;
|