зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1166207 - Load preload.js in the Nuwa process. r=khuey
--HG-- extra : rebase_source : 292c5e5dbee5fa49a78fd1997d97094ef2190143
This commit is contained in:
Родитель
1f8f5b63b0
Коммит
3c09a9761d
|
@ -1757,4 +1757,13 @@ BrowserElementChild.prototype = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var api = new BrowserElementChild();
|
var api = null;
|
||||||
|
if ('DoPreloadPostfork' in this && typeof this.DoPreloadPostfork === 'function') {
|
||||||
|
// If we are preloaded, instantiate BrowserElementChild after a content
|
||||||
|
// process is forked.
|
||||||
|
this.DoPreloadPostfork(function() {
|
||||||
|
api = new BrowserElementChild();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
api = new BrowserElementChild();
|
||||||
|
}
|
||||||
|
|
|
@ -2291,11 +2291,7 @@ ContentChild::RecvAppInit()
|
||||||
// PreloadSlowThings() may set the docshell of the first TabChild
|
// PreloadSlowThings() may set the docshell of the first TabChild
|
||||||
// inactive, and we can only safely restore it to active from
|
// inactive, and we can only safely restore it to active from
|
||||||
// BrowserElementChild.js.
|
// BrowserElementChild.js.
|
||||||
if ((mIsForApp || mIsForBrowser)
|
if (mIsForApp || mIsForBrowser) {
|
||||||
#ifdef MOZ_NUWA_PROCESS
|
|
||||||
&& !IsNuwaProcess()
|
|
||||||
#endif
|
|
||||||
) {
|
|
||||||
PreloadSlowThings();
|
PreloadSlowThings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,9 @@
|
||||||
#include "mozilla/plugins/PluginWidgetChild.h"
|
#include "mozilla/plugins/PluginWidgetChild.h"
|
||||||
#include "mozilla/IMEStateManager.h"
|
#include "mozilla/IMEStateManager.h"
|
||||||
#include "mozilla/ipc/DocumentRendererChild.h"
|
#include "mozilla/ipc/DocumentRendererChild.h"
|
||||||
|
#ifdef MOZ_NUWA_PROCESS
|
||||||
|
#include "ipc/Nuwa.h"
|
||||||
|
#endif
|
||||||
#include "mozilla/ipc/FileDescriptorUtils.h"
|
#include "mozilla/ipc/FileDescriptorUtils.h"
|
||||||
#include "mozilla/layers/APZCCallbackHelper.h"
|
#include "mozilla/layers/APZCCallbackHelper.h"
|
||||||
#include "mozilla/layers/APZCTreeManager.h"
|
#include "mozilla/layers/APZCTreeManager.h"
|
||||||
|
@ -450,10 +453,67 @@ TabChild::FindTabChild(const TabId& aTabId)
|
||||||
return tabChild.forget();
|
return tabChild.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
PreloadSlowThingsPostFork(void* aUnused)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIObserverService> observerService =
|
||||||
|
mozilla::services::GetObserverService();
|
||||||
|
observerService->NotifyObservers(nullptr, "preload-postfork", nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MOZ_NUWA_PROCESS
|
||||||
|
class MessageChannelAutoBlock MOZ_STACK_CLASS
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MessageChannelAutoBlock()
|
||||||
|
{
|
||||||
|
SetMessageChannelBlocked(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
~MessageChannelAutoBlock()
|
||||||
|
{
|
||||||
|
SetMessageChannelBlocked(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SetMessageChannelBlocked(bool aBlock)
|
||||||
|
{
|
||||||
|
if (!IsNuwaProcess()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mozilla::dom::ContentChild* content =
|
||||||
|
mozilla::dom::ContentChild::GetSingleton();
|
||||||
|
if (aBlock) {
|
||||||
|
content->GetIPCChannel()->Block();
|
||||||
|
} else {
|
||||||
|
content->GetIPCChannel()->Unblock();
|
||||||
|
}
|
||||||
|
|
||||||
|
nsTArray<IToplevelProtocol*> actors;
|
||||||
|
content->GetOpenedActors(actors);
|
||||||
|
for (size_t j = 0; j < actors.Length(); j++) {
|
||||||
|
IToplevelProtocol* actor = actors[j];
|
||||||
|
if (aBlock) {
|
||||||
|
actor->GetIPCChannel()->Block();
|
||||||
|
} else {
|
||||||
|
actor->GetIPCChannel()->Unblock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static bool sPreloaded = false;
|
||||||
|
|
||||||
/*static*/ void
|
/*static*/ void
|
||||||
TabChild::PreloadSlowThings()
|
TabChild::PreloadSlowThings()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!sPreallocatedTab);
|
if (sPreloaded) {
|
||||||
|
// If we are alredy initialized in Nuwa, don't redo preloading.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sPreloaded = true;
|
||||||
|
|
||||||
// Pass nullptr to aManager since at this point the TabChild is
|
// Pass nullptr to aManager since at this point the TabChild is
|
||||||
// not connected to any manager. Any attempt to use the TabChild
|
// not connected to any manager. Any attempt to use the TabChild
|
||||||
|
@ -465,6 +525,13 @@ TabChild::PreloadSlowThings()
|
||||||
!tab->InitTabChildGlobal(DONT_LOAD_SCRIPTS)) {
|
!tab->InitTabChildGlobal(DONT_LOAD_SCRIPTS)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MOZ_NUWA_PROCESS
|
||||||
|
// Temporarily block the IPC channels to the chrome process when we are
|
||||||
|
// preloading.
|
||||||
|
MessageChannelAutoBlock autoblock;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Just load and compile these scripts, but don't run them.
|
// Just load and compile these scripts, but don't run them.
|
||||||
tab->TryCacheLoadAndCompileScript(BROWSER_ELEMENT_CHILD_SCRIPT, true);
|
tab->TryCacheLoadAndCompileScript(BROWSER_ELEMENT_CHILD_SCRIPT, true);
|
||||||
// Load, compile, and run these scripts.
|
// Load, compile, and run these scripts.
|
||||||
|
@ -472,6 +539,16 @@ TabChild::PreloadSlowThings()
|
||||||
NS_LITERAL_STRING("chrome://global/content/preload.js"),
|
NS_LITERAL_STRING("chrome://global/content/preload.js"),
|
||||||
true);
|
true);
|
||||||
|
|
||||||
|
#ifdef MOZ_NUWA_PROCESS
|
||||||
|
if (IsNuwaProcess()) {
|
||||||
|
NuwaAddFinalConstructor(PreloadSlowThingsPostFork, nullptr);
|
||||||
|
} else {
|
||||||
|
PreloadSlowThingsPostFork(nullptr);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
PreloadSlowThingsPostFork(nullptr);
|
||||||
|
#endif
|
||||||
|
|
||||||
nsCOMPtr<nsIDocShell> docShell = do_GetInterface(tab->WebNavigation());
|
nsCOMPtr<nsIDocShell> docShell = do_GetInterface(tab->WebNavigation());
|
||||||
if (nsIPresShell* presShell = docShell->GetPresShell()) {
|
if (nsIPresShell* presShell = docShell->GetPresShell()) {
|
||||||
// Initialize and do an initial reflow of the about:blank
|
// Initialize and do an initial reflow of the about:blank
|
||||||
|
|
|
@ -9,6 +9,17 @@
|
||||||
|
|
||||||
const BrowserElementIsPreloaded = true;
|
const BrowserElementIsPreloaded = true;
|
||||||
|
|
||||||
|
const DoPreloadPostfork = function(aCallback) {
|
||||||
|
Services.obs.addObserver({
|
||||||
|
_callback: aCallback,
|
||||||
|
|
||||||
|
observe: function() {
|
||||||
|
this._callback();
|
||||||
|
Services.obs.removeObserver(this, "preload-postfork");
|
||||||
|
}
|
||||||
|
}, "preload-postfork", false);
|
||||||
|
};
|
||||||
|
|
||||||
(function (global) {
|
(function (global) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
@ -16,7 +27,6 @@ const BrowserElementIsPreloaded = true;
|
||||||
let Cc = Components.classes;
|
let Cc = Components.classes;
|
||||||
let Ci = Components.interfaces;
|
let Ci = Components.interfaces;
|
||||||
|
|
||||||
Cu.import("resource://gre/modules/AppsServiceChild.jsm");
|
|
||||||
Cu.import("resource://gre/modules/AppsUtils.jsm");
|
Cu.import("resource://gre/modules/AppsUtils.jsm");
|
||||||
Cu.import("resource://gre/modules/BrowserElementPromptService.jsm");
|
Cu.import("resource://gre/modules/BrowserElementPromptService.jsm");
|
||||||
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
|
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
|
||||||
|
@ -30,12 +40,10 @@ const BrowserElementIsPreloaded = true;
|
||||||
|
|
||||||
Cc["@mozilla.org/appshell/appShellService;1"].getService(Ci["nsIAppShellService"]);
|
Cc["@mozilla.org/appshell/appShellService;1"].getService(Ci["nsIAppShellService"]);
|
||||||
Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci["nsIWindowMediator"]);
|
Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci["nsIWindowMediator"]);
|
||||||
Cc["@mozilla.org/AppsService;1"].getService(Ci["nsIAppsService"]);
|
|
||||||
Cc["@mozilla.org/base/telemetry;1"].getService(Ci["nsITelemetry"]);
|
Cc["@mozilla.org/base/telemetry;1"].getService(Ci["nsITelemetry"]);
|
||||||
Cc["@mozilla.org/categorymanager;1"].getService(Ci["nsICategoryManager"]);
|
Cc["@mozilla.org/categorymanager;1"].getService(Ci["nsICategoryManager"]);
|
||||||
Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci["nsIMessageSender"]);
|
Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci["nsIMessageSender"]);
|
||||||
Cc["@mozilla.org/consoleservice;1"].getService(Ci["nsIConsoleService"]);
|
Cc["@mozilla.org/consoleservice;1"].getService(Ci["nsIConsoleService"]);
|
||||||
Cc["@mozilla.org/cookieService;1"].getService(Ci["nsICookieService"]);
|
|
||||||
Cc["@mozilla.org/docshell/urifixup;1"].getService(Ci["nsIURIFixup"]);
|
Cc["@mozilla.org/docshell/urifixup;1"].getService(Ci["nsIURIFixup"]);
|
||||||
Cc["@mozilla.org/dom/dom-request-service;1"].getService(Ci["nsIDOMRequestService"]);
|
Cc["@mozilla.org/dom/dom-request-service;1"].getService(Ci["nsIDOMRequestService"]);
|
||||||
Cc["@mozilla.org/embedcomp/prompt-service;1"].getService(Ci["nsIPromptService"]);
|
Cc["@mozilla.org/embedcomp/prompt-service;1"].getService(Ci["nsIPromptService"]);
|
||||||
|
@ -53,14 +61,12 @@ const BrowserElementIsPreloaded = true;
|
||||||
Cc["@mozilla.org/network/idn-service;1"].getService(Ci["nsIIDNService"]);
|
Cc["@mozilla.org/network/idn-service;1"].getService(Ci["nsIIDNService"]);
|
||||||
Cc["@mozilla.org/network/io-service;1"].getService(Ci["nsIIOService2"]);
|
Cc["@mozilla.org/network/io-service;1"].getService(Ci["nsIIOService2"]);
|
||||||
Cc["@mozilla.org/network/mime-hdrparam;1"].getService(Ci["nsIMIMEHeaderParam"]);
|
Cc["@mozilla.org/network/mime-hdrparam;1"].getService(Ci["nsIMIMEHeaderParam"]);
|
||||||
Cc["@mozilla.org/network/protocol-proxy-service;1"].getService(Ci["nsIProtocolProxyService"]);
|
|
||||||
Cc["@mozilla.org/network/socket-transport-service;1"].getService(Ci["nsISocketTransportService"]);
|
Cc["@mozilla.org/network/socket-transport-service;1"].getService(Ci["nsISocketTransportService"]);
|
||||||
Cc["@mozilla.org/network/stream-transport-service;1"].getService(Ci["nsIStreamTransportService"]);
|
Cc["@mozilla.org/network/stream-transport-service;1"].getService(Ci["nsIStreamTransportService"]);
|
||||||
Cc["@mozilla.org/network/url-parser;1?auth=maybe"].getService(Ci["nsIURLParser"]);
|
Cc["@mozilla.org/network/url-parser;1?auth=maybe"].getService(Ci["nsIURLParser"]);
|
||||||
Cc["@mozilla.org/network/url-parser;1?auth=no"].getService(Ci["nsIURLParser"]);
|
Cc["@mozilla.org/network/url-parser;1?auth=no"].getService(Ci["nsIURLParser"]);
|
||||||
Cc["@mozilla.org/network/url-parser;1?auth=yes"].getService(Ci["nsIURLParser"]);
|
Cc["@mozilla.org/network/url-parser;1?auth=yes"].getService(Ci["nsIURLParser"]);
|
||||||
Cc["@mozilla.org/observer-service;1"].getService(Ci["nsIObserverService"]);
|
Cc["@mozilla.org/observer-service;1"].getService(Ci["nsIObserverService"]);
|
||||||
Cc["@mozilla.org/permissionmanager;1"].getService(Ci["nsIPermissionManager"]);
|
|
||||||
Cc["@mozilla.org/preferences-service;1"].getService(Ci["nsIPrefBranch"]);
|
Cc["@mozilla.org/preferences-service;1"].getService(Ci["nsIPrefBranch"]);
|
||||||
Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci["nsIScriptSecurityManager"]);
|
Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci["nsIScriptSecurityManager"]);
|
||||||
Cc["@mozilla.org/storage/service;1"].getService(Ci["mozIStorageService"]);
|
Cc["@mozilla.org/storage/service;1"].getService(Ci["mozIStorageService"]);
|
||||||
|
@ -70,7 +76,6 @@ const BrowserElementIsPreloaded = true;
|
||||||
Cc["@mozilla.org/uriloader;1"].getService(Ci["nsIURILoader"]);
|
Cc["@mozilla.org/uriloader;1"].getService(Ci["nsIURILoader"]);
|
||||||
Cc["@mozilla.org/cspcontext;1"].createInstance(Ci["nsIContentSecurityPolicy"]);
|
Cc["@mozilla.org/cspcontext;1"].createInstance(Ci["nsIContentSecurityPolicy"]);
|
||||||
Cc["@mozilla.org/settingsManager;1"].createInstance(Ci["nsISupports"]);
|
Cc["@mozilla.org/settingsManager;1"].createInstance(Ci["nsISupports"]);
|
||||||
Cc["@mozilla.org/webapps;1"].createInstance(Ci["nsISupports"]);
|
|
||||||
|
|
||||||
/* Applications Specific Helper */
|
/* Applications Specific Helper */
|
||||||
try {
|
try {
|
||||||
|
@ -104,7 +109,44 @@ const BrowserElementIsPreloaded = true;
|
||||||
Services.io.getProtocolHandler("app");
|
Services.io.getProtocolHandler("app");
|
||||||
Services.io.getProtocolHandler("default");
|
Services.io.getProtocolHandler("default");
|
||||||
|
|
||||||
docShell.isActive = false;
|
// Register an observer for topic "preload_postfork" after we fork a content
|
||||||
docShell.createAboutBlankContentViewer(null);
|
// process.
|
||||||
|
DoPreloadPostfork(function () {
|
||||||
|
// Load AppsServiceChild.jsm after fork since it sends an async message to
|
||||||
|
// the chrome process in its init() function.
|
||||||
|
Cu.import("resource://gre/modules/AppsServiceChild.jsm");
|
||||||
|
|
||||||
|
// Load UserCustomizations.jsm after fork since it sends an async message to
|
||||||
|
// the chrome process in its init() function.
|
||||||
|
try {
|
||||||
|
if (Services.prefs.getBoolPref("dom.apps.customization.enabled")) {
|
||||||
|
Cu.import("resource://gre/modules/UserCustomizations.jsm");
|
||||||
|
}
|
||||||
|
} catch(e) {}
|
||||||
|
|
||||||
|
// Load nsIAppsService after fork since its implementation loads
|
||||||
|
// AppsServiceChild.jsm
|
||||||
|
Cc["@mozilla.org/AppsService;1"].getService(Ci["nsIAppsService"]);
|
||||||
|
|
||||||
|
// Load nsICookieService after fork since it sends an IPC constructor
|
||||||
|
// message to the chrome process.
|
||||||
|
Cc["@mozilla.org/cookieService;1"].getService(Ci["nsICookieService"]);
|
||||||
|
|
||||||
|
// Load nsIPermissionManager after fork since it sends a message to the
|
||||||
|
// chrome process to read permissions.
|
||||||
|
Cc["@mozilla.org/permissionmanager;1"].getService(Ci["nsIPermissionManager"]);
|
||||||
|
|
||||||
|
// Create this instance after fork since it loads AppsServiceChild.jsm
|
||||||
|
Cc["@mozilla.org/webapps;1"].createInstance(Ci["nsISupports"]);
|
||||||
|
|
||||||
|
// Load nsIProtocolProxyService after fork since it asynchronously accesses
|
||||||
|
// the "Proxy Resolution" thread after it's frozen.
|
||||||
|
Cc["@mozilla.org/network/protocol-proxy-service;1"].getService(Ci["nsIProtocolProxyService"]);
|
||||||
|
|
||||||
|
// Call docShell.createAboutBlankContentViewer() after fork since it has IPC
|
||||||
|
// activity in the PCompositor protocol.
|
||||||
|
docShell.createAboutBlankContentViewer(null);
|
||||||
|
docShell.isActive = false;
|
||||||
|
});
|
||||||
})(this);
|
})(this);
|
||||||
|
|
||||||
|
|
|
@ -175,6 +175,16 @@ class MessageChannel : HasResultCodes
|
||||||
sIsPumpingMessages = aIsPumping;
|
sIsPumpingMessages = aIsPumping;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MOZ_NUWA_PROCESS
|
||||||
|
void Block() {
|
||||||
|
mLink->Block();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Unblock() {
|
||||||
|
mLink->Unblock();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef OS_WIN
|
#ifdef OS_WIN
|
||||||
struct MOZ_STACK_CLASS SyncStackFrame
|
struct MOZ_STACK_CLASS SyncStackFrame
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,6 +16,10 @@
|
||||||
#include "mozilla/dom/PContent.h"
|
#include "mozilla/dom/PContent.h"
|
||||||
#include "mozilla/dom/PNuwa.h"
|
#include "mozilla/dom/PNuwa.h"
|
||||||
#include "mozilla/hal_sandbox/PHal.h"
|
#include "mozilla/hal_sandbox/PHal.h"
|
||||||
|
#if defined(DEBUG) || defined(ENABLE_TESTS)
|
||||||
|
#include "jsprf.h"
|
||||||
|
extern "C" char* PrintJSStack();
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "mozilla/Assertions.h"
|
#include "mozilla/Assertions.h"
|
||||||
|
@ -75,6 +79,7 @@ ProcessLink::ProcessLink(MessageChannel *aChan)
|
||||||
, mExistingListener(nullptr)
|
, mExistingListener(nullptr)
|
||||||
#ifdef MOZ_NUWA_PROCESS
|
#ifdef MOZ_NUWA_PROCESS
|
||||||
, mIsToNuwaProcess(false)
|
, mIsToNuwaProcess(false)
|
||||||
|
, mIsBlocked(false)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -175,6 +180,8 @@ ProcessLink::SendMessage(Message *msg)
|
||||||
mChan->mMonitor->AssertCurrentThreadOwns();
|
mChan->mMonitor->AssertCurrentThreadOwns();
|
||||||
|
|
||||||
#ifdef MOZ_NUWA_PROCESS
|
#ifdef MOZ_NUWA_PROCESS
|
||||||
|
// Parent to child: check whether we are sending some unexpected message to
|
||||||
|
// the Nuwa process.
|
||||||
if (mIsToNuwaProcess && mozilla::dom::ContentParent::IsNuwaReady()) {
|
if (mIsToNuwaProcess && mozilla::dom::ContentParent::IsNuwaReady()) {
|
||||||
switch (msg->type()) {
|
switch (msg->type()) {
|
||||||
case mozilla::dom::PNuwa::Msg_Fork__ID:
|
case mozilla::dom::PNuwa::Msg_Fork__ID:
|
||||||
|
@ -193,6 +200,19 @@ ProcessLink::SendMessage(Message *msg)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Nuwa to parent: check whether we are currently blocked.
|
||||||
|
if (IsNuwaProcess() && mIsBlocked) {
|
||||||
|
#if defined(ENABLE_TESTS) || defined(DEBUG)
|
||||||
|
char* jsstack = PrintJSStack();
|
||||||
|
printf_stderr("Fatal error: sending a message to the chrome process"
|
||||||
|
"with a blocked IPC channel from \n%s",
|
||||||
|
jsstack ? jsstack : "<no JS stack>");
|
||||||
|
JS_smprintf_free(jsstack);
|
||||||
|
MOZ_CRASH();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mIOLoop->PostTask(
|
mIOLoop->PostTask(
|
||||||
|
|
|
@ -128,6 +128,12 @@ class MessageLink
|
||||||
virtual bool Unsound_IsClosed() const = 0;
|
virtual bool Unsound_IsClosed() const = 0;
|
||||||
virtual uint32_t Unsound_NumQueuedMessages() const = 0;
|
virtual uint32_t Unsound_NumQueuedMessages() const = 0;
|
||||||
|
|
||||||
|
#ifdef MOZ_NUWA_PROCESS
|
||||||
|
// To be overridden by ProcessLink.
|
||||||
|
virtual void Block() {}
|
||||||
|
virtual void Unblock() {}
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MessageChannel *mChan;
|
MessageChannel *mChan;
|
||||||
};
|
};
|
||||||
|
@ -175,12 +181,22 @@ class ProcessLink
|
||||||
virtual bool Unsound_IsClosed() const override;
|
virtual bool Unsound_IsClosed() const override;
|
||||||
virtual uint32_t Unsound_NumQueuedMessages() const override;
|
virtual uint32_t Unsound_NumQueuedMessages() const override;
|
||||||
|
|
||||||
|
#ifdef MOZ_NUWA_PROCESS
|
||||||
|
void Block() override {
|
||||||
|
mIsBlocked = true;
|
||||||
|
}
|
||||||
|
void Unblock() override {
|
||||||
|
mIsBlocked = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Transport* mTransport;
|
Transport* mTransport;
|
||||||
MessageLoop* mIOLoop; // thread where IO happens
|
MessageLoop* mIOLoop; // thread where IO happens
|
||||||
Transport::Listener* mExistingListener; // channel's previous listener
|
Transport::Listener* mExistingListener; // channel's previous listener
|
||||||
#ifdef MOZ_NUWA_PROCESS
|
#ifdef MOZ_NUWA_PROCESS
|
||||||
bool mIsToNuwaProcess;
|
bool mIsToNuwaProcess;
|
||||||
|
bool mIsBlocked;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -235,6 +235,8 @@ public:
|
||||||
|
|
||||||
void GetOpenedActors(nsTArray<IToplevelProtocol*>& aActors);
|
void GetOpenedActors(nsTArray<IToplevelProtocol*>& aActors);
|
||||||
|
|
||||||
|
virtual MessageChannel* GetIPCChannel() = 0;
|
||||||
|
|
||||||
// This Unsafe version should only be used when all other threads are
|
// This Unsafe version should only be used when all other threads are
|
||||||
// frozen, since it performs no locking. It also takes a stack-allocated
|
// frozen, since it performs no locking. It also takes a stack-allocated
|
||||||
// array and its size (number of elements) rather than an nsTArray. The Nuwa
|
// array and its size (number of elements) rather than an nsTArray. The Nuwa
|
||||||
|
|
|
@ -2077,4 +2077,28 @@ IsNuwaReady() {
|
||||||
return sNuwaReady;
|
return sNuwaReady;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(DEBUG) || defined(ENABLE_TESTS)
|
||||||
|
MFBT_API void
|
||||||
|
NuwaAssertNotFrozen(unsigned int aThread, const char* aThreadName) {
|
||||||
|
if (!sIsNuwaProcess || !sIsFreezing) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
thread_info_t *tinfo = GetThreadInfo(static_cast<pthread_t>(aThread));
|
||||||
|
if (!tinfo) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((tinfo->flags & TINFO_FLAG_NUWA_SUPPORT) &&
|
||||||
|
!(tinfo->flags & TINFO_FLAG_NUWA_EXPLICIT_CHECKPOINT)) {
|
||||||
|
__android_log_print(ANDROID_LOG_FATAL, "Nuwa",
|
||||||
|
"Fatal error: the Nuwa process is about to deadlock in "
|
||||||
|
"accessing a frozen thread (%s, tid=%d).",
|
||||||
|
aThreadName ? aThreadName : "(unnamed)",
|
||||||
|
tinfo->origNativeThreadID);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|
|
@ -186,6 +186,16 @@ MFBT_API bool IsNuwaProcess();
|
||||||
* @return If the Nuwa process is ready for spawning new processes.
|
* @return If the Nuwa process is ready for spawning new processes.
|
||||||
*/
|
*/
|
||||||
MFBT_API bool IsNuwaReady();
|
MFBT_API bool IsNuwaReady();
|
||||||
|
|
||||||
|
#if defined(DEBUG) || defined(ENABLE_TESTS)
|
||||||
|
/**
|
||||||
|
* Asserts that aThread is not frozen.
|
||||||
|
*/
|
||||||
|
MFBT_API void NuwaAssertNotFrozen(unsigned int aThread,
|
||||||
|
const char* aThreadName);
|
||||||
|
#else
|
||||||
|
#define NuwaAssertNotFrozen(aThread, aThreadName) do {} while(0);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __NUWA_H_ */
|
#endif /* __NUWA_H_ */
|
||||||
|
|
|
@ -41,6 +41,10 @@
|
||||||
#include "nsICrashReporter.h"
|
#include "nsICrashReporter.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef MOZ_NUWA_PROCESS
|
||||||
|
#include "private/pprthred.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef XP_LINUX
|
#ifdef XP_LINUX
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
|
@ -511,6 +515,12 @@ nsThread::PutEvent(already_AddRefed<nsIRunnable>&& aEvent, nsNestedEventTarget*
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIThreadObserver> obs;
|
nsCOMPtr<nsIThreadObserver> obs;
|
||||||
|
|
||||||
|
#ifdef MOZ_NUWA_PROCESS
|
||||||
|
// On debug build or when tests are enabled, assert that we are not about to
|
||||||
|
// create a deadlock in the Nuwa process.
|
||||||
|
NuwaAssertNotFrozen(PR_GetThreadID(mThread), PR_GetThreadName(mThread));
|
||||||
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
MutexAutoLock lock(mLock);
|
MutexAutoLock lock(mLock);
|
||||||
nsChainedEventQueue* queue = aTarget ? aTarget->mQueue : &mEventsRoot;
|
nsChainedEventQueue* queue = aTarget ? aTarget->mQueue : &mEventsRoot;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче