Bug 1285373 P1 Allow addon-sdk unloader to hold callbacks weakly. r=gabor
authorBen Kelly <ben@wanderview.com>
Wed, 20 Jul 2016 06:47:23 -0700
changeset 345933 01793fbeacfd55d5ea9c6685d1a571c965754949
parent 345932 fa663127d37bd77c3eb92f75879b1ff603995187
child 345934 8aa72f37debb9e3c0a556dc42f08863109392065
push id6389
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:38:22 +0000
treeherdermozilla-beta@01d67bfe6c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgabor
bugs1285373
milestone50.0a1
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 1285373 P1 Allow addon-sdk unloader to hold callbacks weakly. r=gabor
addon-sdk/source/lib/sdk/system/unload.js
--- a/addon-sdk/source/lib/sdk/system/unload.js
+++ b/addon-sdk/source/lib/sdk/system/unload.js
@@ -5,26 +5,43 @@
 // Parts of this module were taken from narwhal:
 //
 // http://narwhaljs.org
 
 module.metadata = {
   "stability": "experimental"
 };
 
+const { Cu } = require('chrome');
 const { on, off } = require('./events');
 const unloadSubject = require('@loader/unload');
 
 const observers = [];
 const unloaders = [];
 
-var when = exports.when = function when(observer) {
-  if (observers.indexOf(observer) != -1)
-    return;
-  observers.unshift(observer);
+function WeakObserver(inner) {
+  this._inner = Cu.getWeakReference(inner);
+}
+
+Object.defineProperty(WeakObserver.prototype, 'value', {
+  get: function() { this._inner.get() }
+});
+
+var when = exports.when = function when(observer, opts) {
+  opts = opts || {};
+  for (var i = 0; i < observers.length; ++i) {
+    if (observers[i] === observer || observers[i].value === observer) {
+      return;
+    }
+  }
+  if (opts.weak) {
+    observers.unshift(new WeakObserver(observer));
+  } else {
+    observers.unshift(observer);
+  }
 };
 
 var ensure = exports.ensure = function ensure(obj, destructorName) {
   if (!destructorName)
     destructorName = "unload";
   if (!(destructorName in obj))
     throw new Error("object has no '" + destructorName + "' property");
 
@@ -50,17 +67,22 @@ var ensure = exports.ensure = function e
   unloaders.push(unloadWrapper);
 
   obj[destructorName] = unloadWrapper;
 };
 
 function unload(reason) {
   observers.forEach(function(observer) {
     try {
-      observer(reason);
+      if (observer instanceof WeakObserver) {
+        observer = observer.value;
+      }
+      if (typeof observer === 'function') {
+        observer(reason);
+      }
     }
     catch (error) {
       console.exception(error);
     }
   });
 }
 
 when(function(reason) {