Bug 612551 - Clear appshell observers on xpcom-shutdown. r=blassey a=blocking-fennec
authorJosh Matthews <josh@joshmatthews.net>
Tue, 21 Dec 2010 13:28:45 -0800
changeset 60299 e28ce34157f14821034ca8157fbbd2ad67c27ee0
parent 60298 7a5beb46743f7f0811e5551d93c7a49c1ca739b5
child 60300 a36ba194fd7cdde6c86edceb205f9a67fa704f51
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersblassey, blocking-fennec
bugs612551
milestone2.0b10pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 612551 - Clear appshell observers on xpcom-shutdown. r=blassey a=blocking-fennec
widget/src/android/nsAppShell.cpp
widget/src/android/nsAppShell.h
--- a/widget/src/android/nsAppShell.cpp
+++ b/widget/src/android/nsAppShell.cpp
@@ -70,16 +70,18 @@ using namespace mozilla;
 PRLogModuleInfo *gWidgetLog = nsnull;
 #endif
 
 nsAccelerometerSystem *gAccel = nsnull;
 nsIGeolocationUpdate *gLocationCallback = nsnull;
 
 nsAppShell *nsAppShell::gAppShell = nsnull;
 
+NS_IMPL_ISUPPORTS_INHERITED1(nsAppShell, nsBaseAppShell, nsIObserver)
+
 nsAppShell::nsAppShell()
     : mQueueLock(nsnull),
       mCondLock(nsnull),
       mQueueCond(nsnull),
       mNumDraws(0)
 {
     gAppShell = this;
 }
@@ -109,19 +111,37 @@ nsAppShell::Init()
     mCondLock = PR_NewLock();
     mQueueCond = PR_NewCondVar(mCondLock);
 
     mObserversHash.Init();
 
     nsresult rv = nsBaseAppShell::Init();
     if (AndroidBridge::Bridge())
         AndroidBridge::Bridge()->NotifyAppShellReady();
+
+    nsCOMPtr<nsIObserverService> obsServ =
+            mozilla::services::GetObserverService();
+    if (obsServ) {
+        obsServ->AddObserver(this, "xpcom-shutdown", PR_FALSE);
+    }
     return rv;
 }
 
+NS_IMETHODIMP
+nsAppShell::Observe(nsISupports* aSubject,
+                    const char* aTopic,
+                    const PRUnichar* aData)
+{
+    if (!strcmp(aTopic, "xpcom-shutdown")) {
+        // We need to ensure no observers stick around after XPCOM shuts down
+        // or we'll see crashes, as the app shell outlives XPConnect.
+        mObserversHash.Clear();
+    }
+    return nsBaseAppShell::Observe(aSubject, aTopic, aData);
+}
 
 void
 nsAppShell::ScheduleNativeEventCallback()
 {
     EVLOG("nsAppShell::ScheduleNativeEventCallback pth: %p thread: %p main: %d", (void*) pthread_self(), (void*) NS_GetCurrentThread(), NS_IsMainThread());
 
     // this is valid to be called from any thread, so do so.
     PostEvent(new AndroidGeckoEvent(AndroidGeckoEvent::NATIVE_POKE));
--- a/widget/src/android/nsAppShell.h
+++ b/widget/src/android/nsAppShell.h
@@ -56,16 +56,19 @@ class nsAppShell :
     public nsBaseAppShell
 {
 public:
     static nsAppShell *gAppShell;
     static mozilla::AndroidGeckoEvent *gEarlyEvent;
 
     nsAppShell();
 
+    NS_DECL_ISUPPORTS_INHERITED
+    NS_DECL_NSIOBSERVER
+
     nsresult Init();
 
     void NotifyNativeEvent();
 
     virtual PRBool ProcessNextNativeEvent(PRBool mayWait);
 
     void PostEvent(mozilla::AndroidGeckoEvent *event);
     void RemoveNextEvent();