зеркало из https://github.com/mozilla/gecko-dev.git
Bug 780770, nsThread::SetMainThreadObserver, r=bz+bholley
This commit is contained in:
Родитель
5e90f93f45
Коммит
c370341643
|
@ -39,6 +39,7 @@
|
|||
#include "nsWrapperCacheInlines.h"
|
||||
#include "nsDOMMutationObserver.h"
|
||||
#include "nsICycleCollectorListener.h"
|
||||
#include "nsThread.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
using namespace xpc;
|
||||
|
@ -157,13 +158,12 @@ nsXPConnect::GetXPConnect()
|
|||
// balanced by explicit call to ReleaseXPConnectSingleton()
|
||||
NS_ADDREF(gSelf);
|
||||
|
||||
// Add XPConnect as an thread observer.
|
||||
// Set XPConnect as the main thread observer.
|
||||
//
|
||||
// The cycle collector sometimes calls GetXPConnect, but it should never
|
||||
// be the one that initializes gSelf.
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
nsCOMPtr<nsIThreadInternal> thread = do_QueryInterface(NS_GetCurrentThread());
|
||||
if (NS_FAILED(thread->AddObserver(gSelf))) {
|
||||
if (NS_FAILED(nsThread::SetMainThreadObserver(gSelf))) {
|
||||
NS_RELEASE(gSelf);
|
||||
// Fall through to returning null
|
||||
}
|
||||
|
@ -186,14 +186,7 @@ nsXPConnect::ReleaseXPConnectSingleton()
|
|||
{
|
||||
nsXPConnect* xpc = gSelf;
|
||||
if (xpc) {
|
||||
|
||||
// The thread subsystem may have been shut down already, so make sure
|
||||
// to check for null here.
|
||||
nsCOMPtr<nsIThreadInternal> thread = do_QueryInterface(NS_GetCurrentThread());
|
||||
if (thread) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
thread->RemoveObserver(xpc);
|
||||
}
|
||||
nsThread::SetMainThreadObserver(nullptr);
|
||||
|
||||
#ifdef DEBUG
|
||||
// force a dump of the JavaScript gc heap if JS is still alive
|
||||
|
|
|
@ -47,6 +47,8 @@ static PRLogModuleInfo *sLog = PR_NewLogModule("nsThread");
|
|||
|
||||
NS_DECL_CI_INTERFACE_GETTER(nsThread)
|
||||
|
||||
nsIThreadObserver* nsThread::sMainThreadObserver = nullptr;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
// Fun fact: Android's GCC won't convert bool* to int32_t*, so we can't
|
||||
|
@ -580,6 +582,12 @@ nsThread::ProcessNextEvent(bool mayWait, bool *result)
|
|||
}
|
||||
}
|
||||
|
||||
bool notifyMainThreadObserver =
|
||||
(MAIN_THREAD == mIsMainThread) && sMainThreadObserver;
|
||||
if (notifyMainThreadObserver)
|
||||
sMainThreadObserver->OnProcessNextEvent(this, mayWait && !ShuttingDown(),
|
||||
mRunningEvent);
|
||||
|
||||
nsCOMPtr<nsIThreadObserver> obs = mObserver;
|
||||
if (obs)
|
||||
obs->OnProcessNextEvent(this, mayWait && !ShuttingDown(), mRunningEvent);
|
||||
|
@ -624,6 +632,9 @@ nsThread::ProcessNextEvent(bool mayWait, bool *result)
|
|||
if (obs)
|
||||
obs->AfterProcessNextEvent(this, mRunningEvent);
|
||||
|
||||
if (notifyMainThreadObserver && sMainThreadObserver)
|
||||
sMainThreadObserver->AfterProcessNextEvent(this, mRunningEvent);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -732,6 +743,21 @@ nsThread::RemoveObserver(nsIThreadObserver *observer)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsThread::SetMainThreadObserver(nsIThreadObserver* aObserver)
|
||||
{
|
||||
if (aObserver && nsThread::sMainThreadObserver) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
if (!NS_IsMainThread()) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
nsThread::sMainThreadObserver = aObserver;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -50,7 +50,12 @@ public:
|
|||
// Clear the observer list.
|
||||
void ClearObservers() { mEventObservers.Clear(); }
|
||||
|
||||
static nsresult
|
||||
SetMainThreadObserver(nsIThreadObserver* aObserver);
|
||||
|
||||
private:
|
||||
static nsIThreadObserver* sMainThreadObserver;
|
||||
|
||||
friend class nsThreadShutdownEvent;
|
||||
|
||||
~nsThread();
|
||||
|
|
Загрузка…
Ссылка в новой задаче