addon-sdk/source/lib/sdk/system/unload.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 // Parts of this module were taken from narwhal:
michael@0 6 //
michael@0 7 // http://narwhaljs.org
michael@0 8
michael@0 9 module.metadata = {
michael@0 10 "stability": "experimental"
michael@0 11 };
michael@0 12
michael@0 13 const { on, off } = require('./events');
michael@0 14 const unloadSubject = require('@loader/unload');
michael@0 15
michael@0 16 const observers = [];
michael@0 17 const unloaders = [];
michael@0 18
michael@0 19 var when = exports.when = function when(observer) {
michael@0 20 if (observers.indexOf(observer) != -1)
michael@0 21 return;
michael@0 22 observers.unshift(observer);
michael@0 23 };
michael@0 24
michael@0 25 var ensure = exports.ensure = function ensure(obj, destructorName) {
michael@0 26 if (!destructorName)
michael@0 27 destructorName = "unload";
michael@0 28 if (!(destructorName in obj))
michael@0 29 throw new Error("object has no '" + destructorName + "' property");
michael@0 30
michael@0 31 let called = false;
michael@0 32 let originalDestructor = obj[destructorName];
michael@0 33
michael@0 34 function unloadWrapper(reason) {
michael@0 35 if (!called) {
michael@0 36 called = true;
michael@0 37 let index = unloaders.indexOf(unloadWrapper);
michael@0 38 if (index == -1)
michael@0 39 throw new Error("internal error: unloader not found");
michael@0 40 unloaders.splice(index, 1);
michael@0 41 originalDestructor.call(obj, reason);
michael@0 42 originalDestructor = null;
michael@0 43 destructorName = null;
michael@0 44 obj = null;
michael@0 45 }
michael@0 46 };
michael@0 47
michael@0 48 // TODO: Find out why the order is inverted here. It seems that
michael@0 49 // it may be causing issues!
michael@0 50 unloaders.push(unloadWrapper);
michael@0 51
michael@0 52 obj[destructorName] = unloadWrapper;
michael@0 53 };
michael@0 54
michael@0 55 function unload(reason) {
michael@0 56 observers.forEach(function(observer) {
michael@0 57 try {
michael@0 58 observer(reason);
michael@0 59 }
michael@0 60 catch (error) {
michael@0 61 console.exception(error);
michael@0 62 }
michael@0 63 });
michael@0 64 }
michael@0 65
michael@0 66 when(function(reason) {
michael@0 67 unloaders.slice().forEach(function(unloadWrapper) {
michael@0 68 unloadWrapper(reason);
michael@0 69 });
michael@0 70 });
michael@0 71
michael@0 72 on('sdk:loader:destroy', function onunload({ subject, data: reason }) {
michael@0 73 // If this loader is unload then `subject.wrappedJSObject` will be
michael@0 74 // `destructor`.
michael@0 75 if (subject.wrappedJSObject === unloadSubject) {
michael@0 76 off('sdk:loader:destroy', onunload);
michael@0 77 unload(reason);
michael@0 78 }
michael@0 79 // Note that we use strong reference to listener here to make sure it's not
michael@0 80 // GC-ed, which may happen otherwise since nothing keeps reference to `onunolad`
michael@0 81 // function.
michael@0 82 }, true);

mercurial