Bug 768364 - Clear sLockTable on shutdown r=jlebar
authorKan-Ru Chen <kanru@kanru.info>
Fri, 06 Jul 2012 10:09:46 +0800
changeset 98486 214bc2c2eeb25e9b5c1afffe6aadb227f2fd68b8
parent 98485 d64dfd57d873158c6aab632032b3cc776b521540
child 98487 aff063e52fc65bf8bc5b449b4e1ceca477da74b6
push idunknown
push userunknown
push dateunknown
reviewersjlebar
bugs768364
milestone16.0a1
Bug 768364 - Clear sLockTable on shutdown r=jlebar
hal/HalWakeLock.cpp
--- a/hal/HalWakeLock.cpp
+++ b/hal/HalWakeLock.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
 #include "mozilla/Hal.h"
 #include "mozilla/HalWakeLock.h"
-#include "mozilla/ClearOnShutdown.h"
+#include "mozilla/Services.h"
+#include "nsObserverService.h"
 #include "nsDataHashtable.h"
 #include "nsHashKeys.h"
 
 using namespace mozilla::hal;
 
 namespace mozilla {
 namespace hal {
 
@@ -37,24 +38,50 @@ struct LockCount {
   PRUint32 numLocks;
   PRUint32 numHidden;
 };
 }
 
 static int sActiveChildren = 0;
 static nsAutoPtr<nsDataHashtable<nsStringHashKey, LockCount> > sLockTable;
 static bool sInitialized = false;
+static bool sIsShuttingDown = false;
+
+namespace {
+class ClearHashtableOnShutdown : public nsIObserver {
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIOBSERVER
+};
+
+NS_IMPL_ISUPPORTS1(ClearHashtableOnShutdown, nsIObserver)
+
+NS_IMETHODIMP
+ClearHashtableOnShutdown::Observe(nsISupports* aSubject, const char* aTopic, const PRUnichar* data)
+{
+  MOZ_ASSERT(!strcmp(aTopic, "xpcom-shutdown"));
+
+  sIsShuttingDown = true;
+  sLockTable = nsnull;
+
+  return NS_OK;
+}
+} // anonymous namespace
 
 static void
 Init()
 {
   sLockTable = new nsDataHashtable<nsStringHashKey, LockCount>();
   sLockTable->Init();
-  ClearOnShutdown(&sLockTable);
   sInitialized = true;
+
+  nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
+  if (obs) {
+    obs->AddObserver(new ClearHashtableOnShutdown(), "xpcom-shutdown", false);
+  }
 }
 
 void
 EnableWakeLockNotifications()
 {
   sActiveChildren++;
 }
 
@@ -64,16 +91,19 @@ DisableWakeLockNotifications()
   sActiveChildren--;
 }
 
 void
 ModifyWakeLock(const nsAString &aTopic,
                hal::WakeLockControl aLockAdjust,
                hal::WakeLockControl aHiddenAdjust)
 {
+  if (sIsShuttingDown) {
+    return;
+  }
   if (!sInitialized) {
     Init();
   }
 
   LockCount count;
   count.numLocks = 0;
   count.numHidden = 0;
   sLockTable->Get(aTopic, &count);
@@ -102,16 +132,20 @@ ModifyWakeLock(const nsAString &aTopic,
     info.topic() = aTopic;
     NotifyWakeLockChange(info);
   }
 }
 
 void
 GetWakeLockInfo(const nsAString &aTopic, WakeLockInformation *aWakeLockInfo)
 {
+  if (sIsShuttingDown) {
+    NS_WARNING("You don't want to get wake lock information during xpcom-shutdown!");
+    return;
+  }
   if (!sInitialized) {
     Init();
   }
 
   LockCount count;
   count.numLocks = 0;
   count.numHidden = 0;
   sLockTable->Get(aTopic, &count);