Backed out changeset b71c8c052463 (bug 1943846) for causing mass failures. CLOSED...
[gecko.git] / devtools / shared / transport / child-transport.js
blob52511432e54d153aff5c4cb69c3267ff33e1aa53
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 "use strict";
7 const flags = require("resource://devtools/shared/flags.js");
9 /**
10 * A transport for the debugging protocol that uses nsIMessageManagers to
11 * exchange packets with servers running in child processes.
13 * In the parent process, |mm| should be the nsIMessageSender for the
14 * child process. In a child process, |mm| should be the child process
15 * message manager, which sends packets to the parent.
17 * |prefix| is a string included in the message names, to distinguish
18 * multiple servers running in the same child process.
20 * This transport exchanges messages named 'debug:<prefix>:packet', where
21 * <prefix> is |prefix|, whose data is the protocol packet.
23 function ChildDebuggerTransport(mm, prefix) {
24 this._mm = mm;
25 this._messageName = "debug:" + prefix + ":packet";
29 * To avoid confusion, we use 'message' to mean something that
30 * nsIMessageSender conveys, and 'packet' to mean a remote debugging
31 * protocol packet.
33 ChildDebuggerTransport.prototype = {
34 constructor: ChildDebuggerTransport,
36 hooks: null,
38 _addListener() {
39 this._mm.addMessageListener(this._messageName, this);
42 _removeListener() {
43 try {
44 this._mm.removeMessageListener(this._messageName, this);
45 } catch (e) {
46 if (e.result != Cr.NS_ERROR_NULL_POINTER) {
47 throw e;
49 // In some cases, especially when using messageManagers in non-e10s mode, we reach
50 // this point with a dead messageManager which only throws errors but does not
51 // seem to indicate in any other way that it is dead.
55 ready() {
56 this._addListener();
59 close(options) {
60 this._removeListener();
61 if (this.hooks.onTransportClosed) {
62 this.hooks.onTransportClosed(null, options);
66 receiveMessage({ data }) {
67 this.hooks.onPacket(data);
70 /**
71 * Helper method to ensure a given `object` can be sent across message manager
72 * without being serialized to JSON.
73 * See https://searchfox.org/mozilla-central/rev/6bfadf95b4a6aaa8bb3b2a166d6c3545983e179a/dom/base/nsFrameMessageManager.cpp#458-469
75 _canBeSerialized(object) {
76 try {
77 const holder = new StructuredCloneHolder(
78 "ChildDebuggerTransport._canBeSerialized",
79 null,
80 object
82 holder.deserialize(this);
83 } catch (e) {
84 return false;
86 return true;
89 pathToUnserializable(object) {
90 for (const key in object) {
91 const value = object[key];
92 if (!this._canBeSerialized(value)) {
93 if (typeof value == "object") {
94 return [key].concat(this.pathToUnserializable(value));
96 return [key];
99 return [];
102 send(packet) {
103 if (flags.testing && !this._canBeSerialized(packet)) {
104 const attributes = this.pathToUnserializable(packet);
105 let msg =
106 "Following packet can't be serialized: " + JSON.stringify(packet);
107 msg += "\nBecause of attributes: " + attributes.join(", ") + "\n";
108 msg += "Did you pass a function or an XPCOM object in it?";
109 throw new Error(msg);
111 try {
112 this._mm.sendAsyncMessage(this._messageName, packet);
113 } catch (e) {
114 if (e.result != Cr.NS_ERROR_NULL_POINTER) {
115 throw e;
117 // In some cases, especially when using messageManagers in non-e10s mode, we reach
118 // this point with a dead messageManager which only throws errors but does not
119 // seem to indicate in any other way that it is dead.
123 startBulkSend() {
124 throw new Error("Can't send bulk data to child processes.");
128 exports.ChildDebuggerTransport = ChildDebuggerTransport;