Bug 917489 - Fix an observer leak in about:memory. r=mccr8.
authorNicholas Nethercote <nnethercote@mozilla.com>
Tue, 17 Sep 2013 13:13:25 -0700
changeset 147674 6bb1ea0648a284e7c289e69cd81d7e7221dd7ff8
parent 147673 454f59631b74b108c8a7c351e08f8eca50ee2559
child 147675 96d8a2bf056b4fb9c46c58b5f791055fc8e19c55
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersmccr8
bugs917489
milestone27.0a1
Bug 917489 - Fix an observer leak in about:memory. r=mccr8.
toolkit/components/aboutmemory/content/aboutMemory.js
--- a/toolkit/components/aboutmemory/content/aboutMemory.js
+++ b/toolkit/components/aboutmemory/content/aboutMemory.js
@@ -43,22 +43,27 @@ XPCOMUtils.defineLazyGetter(this, "nsFil
                                      "nsIFile", "initWithPath"));
 XPCOMUtils.defineLazyGetter(this, "nsGzipConverter",
                             () => CC("@mozilla.org/streamconv;1?from=gzip&to=uncompressed",
                                      "nsIStreamConverter"));
 
 let gMgr = Cc["@mozilla.org/memory-reporter-manager;1"]
              .getService(Ci.nsIMemoryReporterManager);
 
+// We need to know about "child-memory-reporter-update" events from child
+// processes.
+let gOs = Cc["@mozilla.org/observer-service;1"]
+            .getService(Ci.nsIObserverService);
+gOs.addObserver(updateAboutMemoryFromReporters,
+                "child-memory-reporter-update", false);
+
 let gUnnamedProcessStr = "Main Process";
 
 let gIsDiff = false;
 
-let gChildMemoryListener = undefined;
-
 //---------------------------------------------------------------------------
 
 // Forward slashes in URLs in paths are represented with backslashes to avoid
 // being mistaken for path separators.  Paths/names where this hasn't been
 // undone are prefixed with "unsafe"; the rest are prefixed with "safe".
 function flipBackslashes(aUnsafeStr)
 {
   // Save memory by only doing the replacement if it's necessary.
@@ -110,38 +115,20 @@ function reportAssertionFailure(aMsg)
 function debug(x)
 {
   let section = appendElement(document.body, 'div', 'section');
   appendElementWithText(section, "div", "debug", JSON.stringify(x));
 }
 
 //---------------------------------------------------------------------------
 
-function addChildObserversAndUpdate(aUpdateFn)
-{
-  let os = Cc["@mozilla.org/observer-service;1"]
-             .getService(Ci.nsIObserverService);
-  os.notifyObservers(null, "child-memory-reporter-request", null);
-
-  gChildMemoryListener = aUpdateFn;
-  os.addObserver(gChildMemoryListener, "child-memory-reporter-update", false);
-
-  gChildMemoryListener();
-}
-
 function onUnload()
 {
-  // We need to check if the observer has been added before removing; in some
-  // circumstances (e.g. reloading the page quickly) it might not have because
-  // onLoad might not fire.
-  if (gChildMemoryListener) {
-    let os = Cc["@mozilla.org/observer-service;1"]
-               .getService(Ci.nsIObserverService);
-    os.removeObserver(gChildMemoryListener, "child-memory-reporter-update");
-  }
+  gOs.removeObserver(updateAboutMemoryFromReporters,
+                     "child-memory-reporter-update");
 }
 
 //---------------------------------------------------------------------------
 
 /**
  * Iterates over each reporter.
  *
  * @param aIgnoreReporter
@@ -462,17 +449,22 @@ function doCC()
 function doMMU()
 {
   gMgr.minimizeMemoryUsage(
     () => updateMainAndFooter("Memory minimization completed", HIDE_FOOTER));
 }
 
 function doMeasure()
 {
-  addChildObserversAndUpdate(updateAboutMemoryFromReporters);
+  // Notify any children that they should measure memory consumption, then
+  // update the page.  If any reports come back from children,
+  // updateAboutMemoryFromReporters() will be called again and the page will
+  // regenerate.
+  gOs.notifyObservers(null, "child-memory-reporter-request", null);
+  updateAboutMemoryFromReporters();
 }
 
 /**
  * Top-level function that does the work of generating the page from the memory
  * reporters.
  */
 function updateAboutMemoryFromReporters()
 {