From 1d206cc8267ca37770ff3ae21d84c72ddd263f42 Mon Sep 17 00:00:00 2001 From: Cervantes Yu Date: Tue, 19 May 2015 14:31:25 +0800 Subject: [PATCH] Backout change 39e167bbd14c, a80140872ea5, adae9be2294d and b71ccef9c674 (bug 970307). --- dom/apps/AppsServiceChild.jsm | 9 +- dom/ipc/ContentChild.cpp | 79 ++---- dom/ipc/ContentChild.h | 2 - dom/ipc/ContentParent.cpp | 40 +-- dom/ipc/ContentParent.h | 8 +- dom/ipc/PContent.ipdl | 4 - dom/ipc/TabChild.cpp | 15 -- dom/ipc/TabChild.h | 1 - dom/ipc/jar.mn | 1 - dom/ipc/post-fork-preload.js | 20 -- dom/ipc/preload.js | 2 +- dom/wifi/WifiProxyService.cpp | 3 - dom/workers/WorkerPrivate.cpp | 12 - netwerk/base/nsSocketTransportService2.cpp | 1 - widget/gonk/GonkMemoryPressureMonitoring.cpp | 2 - xpcom/glue/nsThreadUtils.cpp | 8 - xpcom/glue/nsThreadUtils.h | 15 -- xpcom/threads/TimerThread.cpp | 1 - xpcom/threads/nsThread.cpp | 63 +---- xpcom/threads/nsThread.h | 15 -- xpcom/threads/nsThreadManager.cpp | 250 ------------------- xpcom/threads/nsThreadManager.h | 60 ----- xpcom/threads/nsThreadPool.cpp | 7 +- xpcom/threads/nsTimerImpl.cpp | 7 - 24 files changed, 27 insertions(+), 598 deletions(-) delete mode 100644 dom/ipc/post-fork-preload.js diff --git a/dom/apps/AppsServiceChild.jsm b/dom/apps/AppsServiceChild.jsm index 86816225227..8ff625ee924 100644 --- a/dom/apps/AppsServiceChild.jsm +++ b/dom/apps/AppsServiceChild.jsm @@ -103,12 +103,6 @@ this.DOMApplicationRegistry = { this.cpmm.addMessageListener(aMsgName, this); }).bind(this)); - this.resetList(); - - Services.obs.addObserver(this, "xpcom-shutdown", false); - }, - - resetList: function() { this.cpmm.sendAsyncMessage("Webapps:RegisterForMessages", { messages: APPS_IPC_MSG_NAMES }); @@ -116,7 +110,6 @@ this.DOMApplicationRegistry = { // We need to prime the cache with the list of apps. let list = this.cpmm.sendSyncMessage("Webapps:GetList", { })[0]; this.webapps = list.webapps; - // We need a fast mapping from localId -> app, so we add an index. // We also add the manifest to the app object. this.localIdIndex = { }; @@ -125,6 +118,8 @@ this.DOMApplicationRegistry = { this.localIdIndex[app.localId] = app; app.manifest = list.manifests[id]; } + + Services.obs.addObserver(this, "xpcom-shutdown", false); }, observe: function(aSubject, aTopic, aData) { diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index 1f3aae0bedc..b2e6846e554 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -538,12 +538,6 @@ NS_IMPL_ISUPPORTS(BackgroundChildPrimer, nsIIPCBackgroundChildCreateCallback) ContentChild* ContentChild::sSingleton; -static void -PostForkPreload() -{ - TabChild::PostForkPreload(); -} - // Performs initialization that is not fork-safe, i.e. that must be done after // forking from the Nuwa process. static void @@ -554,7 +548,6 @@ InitOnContentProcessCreated() if (IsNuwaProcess()) { return; } - PostForkPreload(); nsCOMPtr permManager = services::GetPermissionManager(); @@ -1356,6 +1349,7 @@ ContentChild::RecvPBrowserConstructor(PBrowserChild* aActor, { // This runs after AllocPBrowserChild() returns and the IPC machinery for this // PBrowserChild has been set up. + nsCOMPtr os = services::GetObserverService(); if (os) { nsITabChild* tc = @@ -2201,11 +2195,8 @@ bool ContentChild::RecvFlushMemory(const nsString& reason) { #ifdef MOZ_NUWA_PROCESS - if (IsNuwaProcess() || ManagedPBrowserChild().Length() == 0) { + if (IsNuwaProcess()) { // Don't flush memory in the nuwa process: the GC thread could be frozen. - // If there's no PBrowser child, don't flush memory, either. GC writes - // to copy-on-write pages and makes preallocated process take more memory - // before it actually becomes an app. return true; } #endif @@ -2299,28 +2290,12 @@ ContentChild::RecvAppInit() // BrowserElementChild.js. if ((mIsForApp || mIsForBrowser) #ifdef MOZ_NUWA_PROCESS - && IsNuwaProcess() + && !IsNuwaProcess() #endif ) { PreloadSlowThings(); -#ifndef MOZ_NUWA_PROCESS - PostForkPreload(); -#endif } -#ifdef MOZ_NUWA_PROCESS - // Some modules are initialized in preloading. We need to wait until the - // tasks they dispatched to chrome process are done. - if (IsNuwaProcess()) { - SendNuwaWaitForFreeze(); - } -#endif - return true; -} - -bool -ContentChild::RecvNuwaFreeze() -{ #ifdef MOZ_NUWA_PROCESS if (IsNuwaProcess()) { ContentChild::GetSingleton()->RecvGarbageCollect(); @@ -2328,6 +2303,7 @@ ContentChild::RecvNuwaFreeze() FROM_HERE, NewRunnableFunction(OnFinishNuwaPreparation)); } #endif + return true; } @@ -2604,36 +2580,6 @@ RunNuwaFork() DoNuwaFork(); } } - -class NuwaForkCaller: public nsRunnable -{ -public: - NS_IMETHODIMP - Run() { - // We want to ensure that the PBackground actor gets cloned in the Nuwa - // process before we freeze. Also, we have to do this to avoid deadlock. - // Protocols that are "opened" (e.g. PBackground, PCompositor) block the - // main thread to wait for the IPC thread during the open operation. - // NuwaSpawnWait() blocks the IPC thread to wait for the main thread when - // the Nuwa process is forked. Unless we ensure that the two cannot happen - // at the same time then we risk deadlock. Spinning the event loop here - // guarantees the ordering is safe for PBackground. - if (!BackgroundChild::GetForCurrentThread()) { - // Dispatch ourself again. - NS_DispatchToMainThread(this, NS_DISPATCH_NORMAL); - } else { - MessageLoop* ioloop = XRE_GetIOMessageLoop(); - ioloop->PostTask(FROM_HERE, NewRunnableFunction(RunNuwaFork)); - } - return NS_OK; - } -private: - virtual - ~NuwaForkCaller() - { - } -}; - #endif bool @@ -2645,9 +2591,22 @@ ContentChild::RecvNuwaFork() } sNuwaForking = true; - nsRefPtr runnable = new NuwaForkCaller(); - NS_DispatchToMainThread(runnable, NS_DISPATCH_NORMAL); + // We want to ensure that the PBackground actor gets cloned in the Nuwa + // process before we freeze. Also, we have to do this to avoid deadlock. + // Protocols that are "opened" (e.g. PBackground, PCompositor) block the + // main thread to wait for the IPC thread during the open operation. + // NuwaSpawnWait() blocks the IPC thread to wait for the main thread when + // the Nuwa process is forked. Unless we ensure that the two cannot happen + // at the same time then we risk deadlock. Spinning the event loop here + // guarantees the ordering is safe for PBackground. + while (!BackgroundChild::GetForCurrentThread()) { + if (NS_WARN_IF(!NS_ProcessNextEvent())) { + return false; + } + } + MessageLoop* ioloop = XRE_GetIOMessageLoop(); + ioloop->PostTask(FROM_HERE, NewRunnableFunction(RunNuwaFork)); return true; #else return false; // Makes the underlying IPC channel abort. diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h index 9470da9b4c0..240bb52429d 100644 --- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -379,8 +379,6 @@ public: virtual bool RecvNotifyPhoneStateChange(const nsString& state) override; - virtual bool RecvNuwaFreeze() override; - void AddIdleObserver(nsIObserver* aObserver, uint32_t aIdleTimeInS); void RemoveIdleObserver(nsIObserver* aObserver, uint32_t aIdleTimeInS); virtual bool RecvNotifyIdleObserver(const uint64_t& aObserver, diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 1ed14e0b9ba..c82390d159b 100755 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -140,7 +140,6 @@ #include "nsServiceManagerUtils.h" #include "nsStyleSheetService.h" #include "nsThreadUtils.h" -#include "nsThreadManager.h" #include "nsToolkitCompsCID.h" #include "nsWidgetsCID.h" #include "PreallocatedProcessManager.h" @@ -1563,28 +1562,6 @@ StaticAutoPtr > NS_IMPL_ISUPPORTS(SystemMessageHandledListener, nsITimerCallback) -#ifdef MOZ_NUWA_PROCESS -class NuwaFreezeListener : public nsThreadManager::AllThreadsWereIdleListener -{ -public: - NuwaFreezeListener(ContentParent* parent) - : mParent(parent) - { - } - - void OnAllThreadsWereIdle() - { - unused << mParent->SendNuwaFreeze(); - nsThreadManager::get()->RemoveAllThreadsWereIdleListener(this); - } -private: - nsRefPtr mParent; - virtual ~NuwaFreezeListener() - { - } -}; -#endif // MOZ_NUWA_PROCESS - } // anonymous namespace void @@ -2362,8 +2339,6 @@ ContentParent::ContentParent(ContentParent* aTemplate, priority = PROCESS_PRIORITY_FOREGROUND; } - mSendPermissionUpdates = aTemplate->mSendPermissionUpdates; - InitInternal(priority, false, /* Setup Off-main thread compositing */ false /* Send registered chrome */); @@ -2527,7 +2502,7 @@ ContentParent::IsForApp() #ifdef MOZ_NUWA_PROCESS bool -ContentParent::IsNuwaProcess() const +ContentParent::IsNuwaProcess() { return mIsNuwaProcess; } @@ -2902,19 +2877,6 @@ ContentParent::RecvNuwaReady() #endif } -bool -ContentParent::RecvNuwaWaitForFreeze() -{ -#ifdef MOZ_NUWA_PROCESS - nsRefPtr listener = new NuwaFreezeListener(this); - nsThreadManager::get()->AddAllThreadsWereIdleListener(listener); - return true; -#else // MOZ_NUWA_PROCESS - NS_ERROR("ContentParent::RecvNuwaWaitForFreeze() not implemented!"); - return false; -#endif // MOZ_NUWA_PROCESS -} - bool ContentParent::RecvAddNewProcess(const uint32_t& aPid, InfallibleTArray&& aFds) diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index bb925615ced..1f04b50f207 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -233,7 +233,7 @@ public: return mIsForBrowser; } #ifdef MOZ_NUWA_PROCESS - bool IsNuwaProcess() const; + bool IsNuwaProcess(); #endif GeckoChildProcessHost* Process() { @@ -247,11 +247,7 @@ public: } bool NeedsPermissionsUpdate() const { -#ifdef MOZ_NUWA_PROCESS - return !IsNuwaProcess() && mSendPermissionUpdates; -#else return mSendPermissionUpdates; -#endif } bool NeedsDataStoreInfos() const { @@ -783,8 +779,6 @@ private: virtual bool RecvNuwaReady() override; - virtual bool RecvNuwaWaitForFreeze() override; - virtual bool RecvAddNewProcess(const uint32_t& aPid, InfallibleTArray&& aFds) override; diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index 82729326978..c380274e661 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -632,7 +632,6 @@ child: InvokeDragSession(IPCDataTransfer[] transfers, uint32_t action); EndDragSession(bool aDoneDrag, bool aUserCancelled); - NuwaFreeze(); async DomainSetChanged(uint32_t aSetType, uint32_t aChangeType, OptionalURIParams aDomain); @@ -899,9 +898,6 @@ parent: async SystemMessageHandled(); NuwaReady(); - // Sent when nuwa finished its initialization process and is waiting for - // parent's signal to make it freeze. - NuwaWaitForFreeze(); sync AddNewProcess(uint32_t pid, ProtocolFdMapping[] aFds); diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index 0389bd7d494..865c740665c 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -775,21 +775,6 @@ TabChild::PreloadSlowThings() ClearOnShutdown(&sPreallocatedTab); } -/*static*/ void -TabChild::PostForkPreload() -{ - // Preallocated Tab can be null if we are forked directly from b2g. In such - // case we don't need to preload anything, just return. - if (!sPreallocatedTab) { - return; - } - - // Rebuild connections to parent. - sPreallocatedTab->RecvLoadRemoteScript( - NS_LITERAL_STRING("chrome://global/content/post-fork-preload.js"), - true); -} - /*static*/ already_AddRefed TabChild::Create(nsIContentChild* aManager, const TabId& aTabId, diff --git a/dom/ipc/TabChild.h b/dom/ipc/TabChild.h index ba38d95ddb1..d3b0f33eab2 100644 --- a/dom/ipc/TabChild.h +++ b/dom/ipc/TabChild.h @@ -263,7 +263,6 @@ public: * on the critical path. */ static void PreloadSlowThings(); - static void PostForkPreload(); /** Return a TabChild with the given attributes. */ static already_AddRefed diff --git a/dom/ipc/jar.mn b/dom/ipc/jar.mn index f71d7ffc8f3..b3f1bc88e0e 100644 --- a/dom/ipc/jar.mn +++ b/dom/ipc/jar.mn @@ -12,4 +12,3 @@ toolkit.jar: content/global/manifestMessages.js (manifestMessages.js) content/global/PushServiceChildPreload.js (../push/PushServiceChildPreload.js) content/global/preload.js (preload.js) - content/global/post-fork-preload.js (post-fork-preload.js) diff --git a/dom/ipc/post-fork-preload.js b/dom/ipc/post-fork-preload.js deleted file mode 100644 index f5238beb2cd..00000000000 --- a/dom/ipc/post-fork-preload.js +++ /dev/null @@ -1,20 +0,0 @@ -/* 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/. */ - -// Preload some things, in an attempt to make app startup faster. -// -// This script is run when the preallocated process starts. It is injected as -// a frame script. -// If Nuwa process is enabled, this script will run in preallocated process -// forked by Nuwa. - -(function (global) { - "use strict"; - - Components.utils.import("resource://gre/modules/AppsServiceChild.jsm"); - Components.classes["@mozilla.org/network/protocol-proxy-service;1"]. - getService(Ci["nsIProtocolProxyService"]); - - DOMApplicationRegistry.resetList(); -})(this); diff --git a/dom/ipc/preload.js b/dom/ipc/preload.js index 0c59d94d4e1..7e613cffd7f 100644 --- a/dom/ipc/preload.js +++ b/dom/ipc/preload.js @@ -6,7 +6,6 @@ // // This script is run when the preallocated process starts. It is injected as // a frame script. -// If nuwa is enabled, this script will run in Nuwa process before frozen. const BrowserElementIsPreloaded = true; @@ -59,6 +58,7 @@ const BrowserElementIsPreloaded = true; Cc["@mozilla.org/network/idn-service;1"].getService(Ci["nsIIDNService"]); Cc["@mozilla.org/network/io-service;1"].getService(Ci["nsIIOService2"]); 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/stream-transport-service;1"].getService(Ci["nsIStreamTransportService"]); Cc["@mozilla.org/network/url-parser;1?auth=maybe"].getService(Ci["nsIURLParser"]); diff --git a/dom/wifi/WifiProxyService.cpp b/dom/wifi/WifiProxyService.cpp index 6efd7df7c08..3257abedeea 100644 --- a/dom/wifi/WifiProxyService.cpp +++ b/dom/wifi/WifiProxyService.cpp @@ -67,9 +67,6 @@ public: NS_IMETHOD Run() { MOZ_ASSERT(!NS_IsMainThread()); -#ifdef MOZ_NUWA_PROCESS - NS_SetIgnoreStatusOfCurrentThread(); -#endif nsAutoString event; gWpaSupplicant->WaitForEvent(event, mInterface); if (!event.IsEmpty()) { diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index f4c7783554a..c3434fc2a30 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -85,7 +85,6 @@ #include "nsQueryObject.h" #include "nsSandboxFlags.h" #include "prthread.h" -#include "nsThread.h" #include "xpcpublic.h" #ifdef ANDROID @@ -5107,17 +5106,6 @@ WorkerPrivate::DoRunLoop(JSContext* aCx) { MutexAutoLock lock(mMutex); -#ifdef MOZ_NUWA_PROCESS - { - nsThread *thr = static_cast(NS_GetCurrentThread()); - ReentrantMonitorAutoEnter mon(thr->ThreadStatusMonitor()); - if (mControlQueue.IsEmpty() && - !(normalRunnablesPending = NS_HasPendingEvents(mThread))) { - thr->SetIdle(); - } - } -#endif // MOZ_NUWA_PROCESS - while (mControlQueue.IsEmpty() && !(debuggerRunnablesPending = !mDebuggerQueue.IsEmpty()) && !(normalRunnablesPending = NS_HasPendingEvents(mThread))) { diff --git a/netwerk/base/nsSocketTransportService2.cpp b/netwerk/base/nsSocketTransportService2.cpp index 0c4d4b9f685..99663532024 100644 --- a/netwerk/base/nsSocketTransportService2.cpp +++ b/netwerk/base/nsSocketTransportService2.cpp @@ -753,7 +753,6 @@ nsSocketTransportService::Run() if (IsNuwaProcess()) { NuwaMarkCurrentThread(nullptr, nullptr); } - NS_SetIgnoreStatusOfCurrentThread(); #endif SOCKET_LOG(("STS thread init\n")); diff --git a/widget/gonk/GonkMemoryPressureMonitoring.cpp b/widget/gonk/GonkMemoryPressureMonitoring.cpp index 374ef85353b..52aa7db2e1c 100644 --- a/widget/gonk/GonkMemoryPressureMonitoring.cpp +++ b/widget/gonk/GonkMemoryPressureMonitoring.cpp @@ -127,8 +127,6 @@ public: } #endif - NS_SetIgnoreStatusOfCurrentThread(); - int lowMemFd = open("/sys/kernel/mm/lowmemkiller/notify_trigger_active", O_RDONLY | O_CLOEXEC); NS_ENSURE_STATE(lowMemFd != -1); diff --git a/xpcom/glue/nsThreadUtils.cpp b/xpcom/glue/nsThreadUtils.cpp index 9346bd1b550..4e33fc4cef3 100644 --- a/xpcom/glue/nsThreadUtils.cpp +++ b/xpcom/glue/nsThreadUtils.cpp @@ -375,11 +375,3 @@ nsAutoLowPriorityIO::~nsAutoLowPriorityIO() #endif } -#ifdef MOZ_NUWA_PROCESS -#ifdef MOZILLA_INTERNAL_API -void -NS_SetIgnoreStatusOfCurrentThread() { - nsThreadManager::get()->SetIgnoreThreadStatus(); -} -#endif // MOZILLA_INTERNAL_API -#endif // MOZ_NUWA_PROCESS diff --git a/xpcom/glue/nsThreadUtils.h b/xpcom/glue/nsThreadUtils.h index 4b173ed4585..e143c6cef9b 100644 --- a/xpcom/glue/nsThreadUtils.h +++ b/xpcom/glue/nsThreadUtils.h @@ -1019,19 +1019,4 @@ private: void NS_SetMainThread(); -/** - * Helpers for thread to report their status when compiled with Nuwa. - */ -#ifdef MOZILLA_INTERNAL_API -#ifdef MOZ_NUWA_PROCESS -extern void -NS_SetIgnoreStatusOfCurrentThread(); -#else // MOZ_NUWA_PROCESS -inline void -NS_SetIgnoreStatusOfCurrentThread() -{ -} -#endif // MOZ_NUWA_PROCESS -#endif // MOZILLA_INTERNAL_API - #endif // nsThreadUtils_h__ diff --git a/xpcom/threads/TimerThread.cpp b/xpcom/threads/TimerThread.cpp index 8d9ba434566..fbdc810597d 100644 --- a/xpcom/threads/TimerThread.cpp +++ b/xpcom/threads/TimerThread.cpp @@ -205,7 +205,6 @@ TimerThread::Run() } #endif - NS_SetIgnoreStatusOfCurrentThread(); MonitorAutoLock lock(mMonitor); // We need to know how many microseconds give a positive PRIntervalTime. This diff --git a/xpcom/threads/nsThread.cpp b/xpcom/threads/nsThread.cpp index d6b9df70766..e69665685ff 100644 --- a/xpcom/threads/nsThread.cpp +++ b/xpcom/threads/nsThread.cpp @@ -15,6 +15,7 @@ #undef LOG #endif +#include "mozilla/ReentrantMonitor.h" #include "nsMemoryPressure.h" #include "nsThreadManager.h" #include "nsIClassInfoImpl.h" @@ -330,10 +331,6 @@ nsThread::ThreadFunc(void* aArg) // Inform the ThreadManager nsThreadManager::get()->RegisterCurrentThread(self); -#ifdef MOZ_NUWA_PROCESS - self->mThreadStatusInfo = - static_cast(nsThreadManager::get()->GetCurrentThreadStatusInfo()); -#endif #if !defined(MOZILLA_XPCOMRT_API) mozilla::IOInterposer::RegisterCurrentThread(); @@ -451,10 +448,6 @@ nsThread::nsThread(MainThreadFlag aMainThread, uint32_t aStackSize) , mShutdownRequired(false) , mEventsAreDoomed(false) , mIsMainThread(aMainThread) -#ifdef MOZ_NUWA_PROCESS - , mThreadStatusMonitor("nsThread.mThreadStatusLock") - , mThreadStatusInfo(nullptr) -#endif { } @@ -502,11 +495,6 @@ nsThread::InitCurrentThread() SetupCurrentThreadForChaosMode(); nsThreadManager::get()->RegisterCurrentThread(this); -#ifdef MOZ_NUWA_PROCESS - mThreadStatusInfo = - static_cast(nsThreadManager::get()->GetCurrentThreadStatusInfo()); -#endif - return NS_OK; } @@ -522,15 +510,7 @@ nsThread::PutEvent(nsIRunnable* aEvent, nsNestedEventTarget* aTarget) NS_WARNING("An event was posted to a thread that will never run it (rejected)"); return NS_ERROR_UNEXPECTED; } -#ifdef MOZ_NUWA_PROCESS - { - ReentrantMonitorAutoEnter mon(mThreadStatusMonitor); - SetWorking(); -#endif // MOZ_NUWA_PROCESS - queue->PutEvent(aEvent); -#ifdef MOZ_NUWA_PROCESS - } -#endif // MOZ_NUWA_PROCESS + queue->PutEvent(aEvent); // Make sure to grab the observer before dropping the lock, otherwise the // event that we just placed into the queue could run and eventually delete @@ -873,27 +853,6 @@ nsThread::ProcessNextEvent(bool aMayWait, bool* aResult) --mNestedEventLoopDepth; -#ifdef MOZ_NUWA_PROCESS - nsCOMPtr notifyAllIdleRunnable; - { - ReentrantMonitorAutoEnter mon(mThreadStatusMonitor); - if ((!mEvents->GetEvent(false, nullptr)) && (mNestedEventLoopDepth == 0)) { - nsThreadManager::get()->SetThreadIsWorking( - static_cast(mThreadStatusInfo), - false, getter_AddRefs(notifyAllIdleRunnable)); - } - } - if (notifyAllIdleRunnable) { - // Dispatching a task leads us to acquire |mLock| of the thread. If we - // dispatch to main thread while holding main thread's - // |mThreadStatusMonitor|, deadlock could happen if other thread is - // blocked by main thread's |mThreadStatusMonitor| and is holding - // main thread's |mLock|. - Dispatch(notifyAllIdleRunnable, NS_DISPATCH_NORMAL); - nsThreadManager::get()->ResetIsDispatchingToMainThread(); - } -#endif // MOZ_NUWA_PROCESS - NOTIFY_EVENT_OBSERVERS(AfterProcessNextEvent, (this, mNestedEventLoopDepth, *aResult)); @@ -1104,24 +1063,6 @@ nsThread::SetMainThreadObserver(nsIThreadObserver* aObserver) return NS_OK; } -#ifdef MOZ_NUWA_PROCESS -void -nsThread::SetWorking() -{ - nsThreadManager::get()->SetThreadIsWorking( - static_cast(mThreadStatusInfo), - true, nullptr); -} - -void -nsThread::SetIdle() -{ - nsThreadManager::get()->SetThreadIsWorking( - static_cast(mThreadStatusInfo), - false, nullptr); -} -#endif - //----------------------------------------------------------------------------- NS_IMETHODIMP diff --git a/xpcom/threads/nsThread.h b/xpcom/threads/nsThread.h index 2f58cb3be60..67e5516a3e8 100644 --- a/xpcom/threads/nsThread.h +++ b/xpcom/threads/nsThread.h @@ -16,7 +16,6 @@ #include "nsTObserverArray.h" #include "mozilla/Attributes.h" #include "nsAutoPtr.h" -#include "mozilla/ReentrantMonitor.h" // A native thread class nsThread @@ -66,14 +65,6 @@ public: static nsresult SetMainThreadObserver(nsIThreadObserver* aObserver); -#ifdef MOZ_NUWA_PROCESS - void SetWorking(); - void SetIdle(); - mozilla::ReentrantMonitor& ThreadStatusMonitor() { - return mThreadStatusMonitor; - } -#endif - protected: static nsIThreadObserver* sMainThreadObserver; @@ -191,12 +182,6 @@ protected: // Set to true when events posted to this thread will never run. bool mEventsAreDoomed; MainThreadFlag mIsMainThread; -#ifdef MOZ_NUWA_PROCESS - mozilla::ReentrantMonitor mThreadStatusMonitor; - // The actual type is defined in nsThreadManager.h which is not exposed to - // file out of thread module. - void* mThreadStatusInfo; -#endif }; //----------------------------------------------------------------------------- diff --git a/xpcom/threads/nsThreadManager.cpp b/xpcom/threads/nsThreadManager.cpp index de3a7a4a17d..bf2868a3691 100644 --- a/xpcom/threads/nsThreadManager.cpp +++ b/xpcom/threads/nsThreadManager.cpp @@ -11,7 +11,6 @@ #include "nsTArray.h" #include "nsAutoPtr.h" #include "mozilla/ThreadLocal.h" -#include "mozilla/ReentrantMonitor.h" #ifdef MOZ_CANARY #include #include @@ -41,45 +40,6 @@ NS_SetMainThread() typedef nsTArray> nsThreadArray; -#ifdef MOZ_NUWA_PROCESS -class NotifyAllThreadsWereIdle: public nsRunnable -{ -public: - - NotifyAllThreadsWereIdle( - nsTArray>* aListeners) - : mListeners(aListeners) - { - } - - virtual NS_IMETHODIMP - Run() { - // Copy listener array, which may be modified during call back. - nsTArray> arr(*mListeners); - for (size_t i = 0; i < arr.Length(); i++) { - arr[i]->OnAllThreadsWereIdle(); - } - return NS_OK; - } - -private: - // Raw pointer, since it's pointing to a member of thread manager. - nsTArray>* mListeners; -}; - -struct nsThreadManager::ThreadStatusInfo { - Atomic mWorking; - Atomic mWillBeWorking; - bool mIgnored; - ThreadStatusInfo() - : mWorking(false) - , mWillBeWorking(false) - , mIgnored(false) - { - } -}; -#endif // MOZ_NUWA_PROCESS - //----------------------------------------------------------------------------- static void @@ -88,24 +48,6 @@ ReleaseObject(void* aData) static_cast(aData)->Release(); } -#ifdef MOZ_NUWA_PROCESS -void -nsThreadManager::DeleteThreadStatusInfo(void* aData) -{ - nsThreadManager* mgr = nsThreadManager::get(); - nsThreadManager::ThreadStatusInfo* thrInfo = - static_cast(aData); - { - ReentrantMonitorAutoEnter mon(*(mgr->mMonitor)); - mgr->mThreadStatusInfos.RemoveElement(thrInfo); - if (NS_IsMainThread()) { - mgr->mMainThreadStatusInfo = nullptr; - } - } - delete thrInfo; -} -#endif - static PLDHashOperator AppendAndRemoveThread(PRThread* aKey, nsRefPtr& aThread, void* aArg) { @@ -147,17 +89,6 @@ nsThreadManager::Init() return NS_ERROR_FAILURE; } -#ifdef MOZ_NUWA_PROCESS - if (PR_NewThreadPrivateIndex( - &mThreadStatusInfoIndex, - nsThreadManager::DeleteThreadStatusInfo) == PR_FAILURE) { - return NS_ERROR_FAILURE; - } -#endif // MOZ_NUWA_PROCESS - -#ifdef MOZ_NUWA_PROCESS - mMonitor = MakeUnique("nsThreadManager.mMonitor"); -#endif // MOZ_NUWA_PROCESS #ifdef MOZ_CANARY const int flags = O_WRONLY | O_APPEND | O_CREAT | O_NONBLOCK; @@ -250,9 +181,6 @@ nsThreadManager::Shutdown() // Remove the TLS entry for the main thread. PR_SetThreadPrivate(mCurThreadIndex, nullptr); -#ifdef MOZ_NUWA_PROCESS - PR_SetThreadPrivate(mThreadStatusInfoIndex, nullptr); -#endif } void @@ -285,9 +213,6 @@ nsThreadManager::UnregisterCurrentThread(nsThread* aThread) PR_SetThreadPrivate(mCurThreadIndex, nullptr); // Ref-count balanced via ReleaseObject -#ifdef MOZ_NUWA_PROCESS - PR_SetThreadPrivate(mThreadStatusInfoIndex, nullptr); -#endif } nsThread* @@ -312,27 +237,6 @@ nsThreadManager::GetCurrentThread() return thread.get(); // reference held in TLS } -#ifdef MOZ_NUWA_PROCESS -nsThreadManager::ThreadStatusInfo* -nsThreadManager::GetCurrentThreadStatusInfo() -{ - void* data = PR_GetThreadPrivate(mThreadStatusInfoIndex); - if (!data) { - ThreadStatusInfo *thrInfo = new ThreadStatusInfo(); - PR_SetThreadPrivate(mThreadStatusInfoIndex, thrInfo); - data = thrInfo; - - ReentrantMonitorAutoEnter mon(*mMonitor); - mThreadStatusInfos.AppendElement(thrInfo); - if (NS_IsMainThread()) { - mMainThreadStatusInfo = thrInfo; - } - } - - return static_cast(data); -} -#endif - NS_IMETHODIMP nsThreadManager::NewThread(uint32_t aCreationFlags, uint32_t aStackSize, @@ -429,157 +333,3 @@ nsThreadManager::GetHighestNumberOfThreads() OffTheBooksMutexAutoLock lock(mLock); return mHighestNumberOfThreads; } - -#ifdef MOZ_NUWA_PROCESS -void -nsThreadManager::SetIgnoreThreadStatus() -{ - GetCurrentThreadStatusInfo()->mIgnored = true; -} - -void -nsThreadManager::SetThreadIdle(nsIRunnable **aReturnRunnable) -{ - SetThreadIsWorking(GetCurrentThreadStatusInfo(), false, aReturnRunnable); -} - -void -nsThreadManager::SetThreadWorking() -{ - SetThreadIsWorking(GetCurrentThreadStatusInfo(), true, nullptr); -} - -void -nsThreadManager::SetThreadIsWorking(ThreadStatusInfo* aInfo, - bool aIsWorking, - nsIRunnable **aReturnRunnable) -{ - aInfo->mWillBeWorking = aIsWorking; - if (mThreadsIdledListeners.Length() > 0) { - - // A race condition occurs since we don't want threads to try to enter the - // monitor (nsThreadManager::mMonitor) when no one cares about their status. - // And thus the race can happen when we put the first listener into - // |mThreadsIdledListeners|: - // - // (1) Thread A wants to dispatch a task to Thread B. - // (2) Thread A checks |mThreadsIdledListeners|, and nothing is in the - // list. So Thread A decides not to enter |mMonitor| when updating B's - // status. - // (3) Thread A is suspended just before it changed status of B. - // (4) A listener is added to |mThreadsIdledListeners| - // (5) Now is Thread C's turn to run. Thread C finds there's something in - // |mThreadsIdledListeners|, so it enters |mMonitor| and check all - // thread info structs in |mThreadStatusInfos| while A is in the middle - // of changing B's status. - // - // Then C may find Thread B is an idle thread (which is not correct, because - // A attempted to change B's status prior to C starting to walk throught - // |mThreadStatusInfo|), but the fact that thread A is working (thread A - // hasn't finished dispatching a task to thread B) can prevent thread C from - // firing a bogus notification. - // - // If the state transition that happens outside the monitor is in the other - // direction, the race condition could be: - // - // (1) Thread D has just finished its jobs and wants to set its status to idle. - // (2) Thread D checks |mThreadsIdledListeners|, and nothing is in the list. - // So Thread D decides not to enter |mMonitor|. - // (3) Thread D is is suspended before it updates its own status. - // (4) A listener is put into |mThreadsIdledListeners|. - // (5) Thread C wants to changes status of itself. It checks - // |mThreadsIdledListeners| and finds something inside the list. Thread C - // then enters |mMonitor|, updates its status and checks thread info in - // |mThreadStatusInfos| while D is changing status of itself out of monitor. - // - // Thread C will find that thread D is working (D actually wants to change its - // status to idle before C starting to check), then C returns without firing - // any notification. Finding that thread D is working can make our checking - // mechanism miss a chance to fire a notification: because thread D thought - // there's nothing in |mThreadsIdledListeners| and thus won't check the - // |mThreadStatusInfos| after changing the status of itself. - // - // |mWillBeWorking| can be used to address this problem. We require each - // thread to put the value that is going to be set to |mWorking| to - // |mWillBeWorking| before the thread decide whether it should enter - // |mMonitor| to change status or not. Thus C finds that D is working while - // D's |mWillBeWorking| is false, and C realizes that D is just updating and - // can treat D as an idle thread. - // - // It doesn't matter whether D will check thread status after changing its - // own status or not. If D checks, which means D will enter the monitor - // before updating status, thus D must be blocked until C has finished - // dispatching the notification task to main thread, and D will find that main - // thread is working and will not fire an additional event. On the other hand, - // if D doesn't check |mThreadStatusInfos|, it's still ok, because C has - // treated D as an idle thread already. - - bool hasWorkingThread = false; - nsRefPtr runnable; - { - ReentrantMonitorAutoEnter mon(*mMonitor); - // Get data structure of thread info. - aInfo->mWorking = aIsWorking; - if (aIsWorking) { - // We are working, so there's no need to check futher. - return; - } - - for (size_t i = 0; i < mThreadStatusInfos.Length(); i++) { - ThreadStatusInfo *info = mThreadStatusInfos[i]; - if (!info->mIgnored) { - if (info->mWorking) { - if (info->mWillBeWorking) { - hasWorkingThread = true; - break; - } - } - } - } - if (!hasWorkingThread && !mDispatchingToMainThread) { - runnable = new NotifyAllThreadsWereIdle(&mThreadsIdledListeners); - mDispatchingToMainThread = true; - } - } - - if (runnable) { - if (NS_IsMainThread()) { - // We are holding the main thread's |nsThread::mThreadStatusMonitor|. - // If we dispatch a task to ourself, then we are in danger of causing - // deadlock. Instead, return the task, and let the caller dispatch it - // for us. - MOZ_ASSERT(aReturnRunnable, - "aReturnRunnable must be provided on main thread"); - runnable.forget(aReturnRunnable); - } else { - NS_DispatchToMainThread(runnable); - ResetIsDispatchingToMainThread(); - } - } - } else { - // Update thread info without holding any lock. - aInfo->mWorking = aIsWorking; - } -} - -void -nsThreadManager::ResetIsDispatchingToMainThread() -{ - ReentrantMonitorAutoEnter mon(*mMonitor); - mDispatchingToMainThread = false; -} - -void -nsThreadManager::AddAllThreadsWereIdleListener(AllThreadsWereIdleListener *listener) -{ - MOZ_ASSERT(GetCurrentThreadStatusInfo()->mWorking); - mThreadsIdledListeners.AppendElement(listener); -} - -void -nsThreadManager::RemoveAllThreadsWereIdleListener(AllThreadsWereIdleListener *listener) -{ - mThreadsIdledListeners.RemoveElement(listener); -} - -#endif // MOZ_NUWA_PROCESS diff --git a/xpcom/threads/nsThreadManager.h b/xpcom/threads/nsThreadManager.h index 32ffda818c3..4acec42213a 100644 --- a/xpcom/threads/nsThreadManager.h +++ b/xpcom/threads/nsThreadManager.h @@ -14,26 +14,9 @@ class nsIRunnable; -namespace mozilla { -class ReentrantMonitor; -} - class nsThreadManager : public nsIThreadManager { public: -#ifdef MOZ_NUWA_PROCESS - struct ThreadStatusInfo; - class AllThreadsWereIdleListener { - public: - NS_INLINE_DECL_REFCOUNTING(AllThreadsWereIdleListener); - virtual void OnAllThreadsWereIdle() = 0; - protected: - virtual ~AllThreadsWereIdleListener() - { - } - }; -#endif // MOZ_NUWA_PROCESS - NS_DECL_ISUPPORTS NS_DECL_NSITHREADMANAGER @@ -71,31 +54,6 @@ public: { } -#ifdef MOZ_NUWA_PROCESS - void SetIgnoreThreadStatus(); - - // |SetThreadWorking| and |SetThreadIdle| set status of thread that is - // currently running. They get thread status information from TLS and pass - // the information to |SetThreadIsWorking|. - void SetThreadIdle(nsIRunnable** aReturnRunnable); - void SetThreadWorking(); - - // |SetThreadIsWorking| is where is status actually changed. Thread status - // information is passed as a argument so caller must obtain the structure - // by itself. If this method is invoked on main thread, |aReturnRunnable| - // should be provided to receive the runnable of notifying listeners. - // |ResetIsDispatchingToMainThread| should be invoked after caller on main - // thread dispatched the task to main thread's queue. - void SetThreadIsWorking(ThreadStatusInfo* aInfo, - bool aIsWorking, - nsIRunnable** aReturnRunnable); - void ResetIsDispatchingToMainThread(); - - void AddAllThreadsWereIdleListener(AllThreadsWereIdleListener *listener); - void RemoveAllThreadsWereIdleListener(AllThreadsWereIdleListener *listener); - ThreadStatusInfo* GetCurrentThreadStatusInfo(); -#endif // MOZ_NUWA_PROCESS - private: nsThreadManager() : mCurThreadIndex(0) @@ -104,11 +62,6 @@ private: , mInitialized(false) , mCurrentNumberOfThreads(1) , mHighestNumberOfThreads(1) -#ifdef MOZ_NUWA_PROCESS - , mMonitor(nullptr) - , mMainThreadStatusInfo(nullptr) - , mDispatchingToMainThread(nullptr) -#endif { } @@ -123,19 +76,6 @@ private: uint32_t mCurrentNumberOfThreads; // The highest number of threads encountered so far during the session uint32_t mHighestNumberOfThreads; - -#ifdef MOZ_NUWA_PROCESS - static void DeleteThreadStatusInfo(void *aData); - unsigned mThreadStatusInfoIndex; - nsTArray> mThreadsIdledListeners; - nsTArray mThreadStatusInfos; - mozilla::UniquePtr mMonitor; - ThreadStatusInfo* mMainThreadStatusInfo; - // |mDispatchingToMainThread| is set when all thread are found to be idle - // before task of notifying all listeners are dispatched to main thread. - // The flag is protected by |mMonitor|. - bool mDispatchingToMainThread; -#endif // MOZ_NUWA_PROCESS }; #define NS_THREADMANAGER_CID \ diff --git a/xpcom/threads/nsThreadPool.cpp b/xpcom/threads/nsThreadPool.cpp index 27538fc8e2b..97fb4a42884 100644 --- a/xpcom/threads/nsThreadPool.cpp +++ b/xpcom/threads/nsThreadPool.cpp @@ -151,6 +151,7 @@ NS_IMETHODIMP nsThreadPool::Run() { LOG(("THRD-P(%p) enter\n", this)); + mThreadNaming.SetThreadPoolName(mName); nsCOMPtr current; @@ -208,9 +209,6 @@ nsThreadPool::Run() } else { PRIntervalTime delta = timeout - (now - idleSince); LOG(("THRD-P(%p) waiting [%d]\n", this, delta)); -#ifdef MOZ_NUWA_PROCESS - nsThreadManager::get()->SetThreadIdle(nullptr); -#endif // MOZ_NUWA_PROCESS mon.Wait(delta); } } else if (wasIdle) { @@ -220,9 +218,6 @@ nsThreadPool::Run() } if (event) { LOG(("THRD-P(%p) running [%p]\n", this, event.get())); -#ifdef MOZ_NUWA_PROCESS - nsThreadManager::get()->SetThreadWorking(); -#endif // MOZ_NUWA_PROCESS event->Run(); } } while (!exitThread); diff --git a/xpcom/threads/nsTimerImpl.cpp b/xpcom/threads/nsTimerImpl.cpp index 5133e63b275..f10fb4dcb6f 100644 --- a/xpcom/threads/nsTimerImpl.cpp +++ b/xpcom/threads/nsTimerImpl.cpp @@ -549,13 +549,6 @@ nsTimerImpl::Fire() return; } -#ifdef MOZ_NUWA_PROCESS - if (IsNuwaProcess() && IsNuwaReady()) { - // A timer event fired after Nuwa frozen can freeze main thread. - return; - } -#endif - #if !defined(MOZILLA_XPCOMRT_API) PROFILER_LABEL("Timer", "Fire", js::ProfileEntry::Category::OTHER);