Bug 780770, nsThread::SetMainThreadObserver, r=bz+bholley

This commit is contained in:
Olli Pettay 2012-10-24 01:26:36 +03:00
Родитель 5e90f93f45
Коммит c370341643
3 изменённых файлов: 35 добавлений и 11 удалений

Просмотреть файл

@ -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();