toolkit/components/url-classifier/content/moz/alarm.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
michael@0 6 // An Alarm fires a callback after a certain amount of time, or at
michael@0 7 // regular intervals. It's a convenient replacement for
michael@0 8 // setTimeout/Interval when you don't want to bind to a specific
michael@0 9 // window.
michael@0 10 //
michael@0 11 // The ConditionalAlarm is an Alarm that cancels itself if its callback
michael@0 12 // returns a value that type-converts to true.
michael@0 13 //
michael@0 14 // Example:
michael@0 15 //
michael@0 16 // function foo() { dump('hi'); };
michael@0 17 // new G_Alarm(foo, 10*1000); // Fire foo in 10 seconds
michael@0 18 // new G_Alarm(foo, 10*1000, true /*repeat*/); // Fire foo every 10 seconds
michael@0 19 // new G_Alarm(foo, 10*1000, true, 7); // Fire foo every 10 seconds
michael@0 20 // // seven times
michael@0 21 // new G_ConditionalAlarm(foo, 1000, true); // Fire every sec until foo()==true
michael@0 22 //
michael@0 23 // // Fire foo every 10 seconds until foo returns true or until it fires seven
michael@0 24 // // times, whichever happens first.
michael@0 25 // new G_ConditionalAlarm(foo, 10*1000, true /*repeating*/, 7);
michael@0 26 //
michael@0 27 // TODO: maybe pass an isFinal flag to the callback if they opted to
michael@0 28 // set maxTimes and this is the last iteration?
michael@0 29
michael@0 30
michael@0 31 /**
michael@0 32 * Set an alarm to fire after a given amount of time, or at specific
michael@0 33 * intervals.
michael@0 34 *
michael@0 35 * @param callback Function to call when the alarm fires
michael@0 36 * @param delayMS Number indicating the length of the alarm period in ms
michael@0 37 * @param opt_repeating Boolean indicating whether this should fire
michael@0 38 * periodically
michael@0 39 * @param opt_maxTimes Number indicating a maximum number of times to
michael@0 40 * repeat (obviously only useful when opt_repeating==true)
michael@0 41 */
michael@0 42 function G_Alarm(callback, delayMS, opt_repeating, opt_maxTimes) {
michael@0 43 this.debugZone = "alarm";
michael@0 44 this.callback_ = callback;
michael@0 45 this.repeating_ = !!opt_repeating;
michael@0 46 this.timer_ = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
michael@0 47 var type = opt_repeating ?
michael@0 48 this.timer_.TYPE_REPEATING_SLACK :
michael@0 49 this.timer_.TYPE_ONE_SHOT;
michael@0 50 this.maxTimes_ = opt_maxTimes ? opt_maxTimes : null;
michael@0 51 this.nTimes_ = 0;
michael@0 52
michael@0 53 this.observerServiceObserver_ = new G_ObserverServiceObserver(
michael@0 54 'xpcom-shutdown',
michael@0 55 BindToObject(this.cancel, this));
michael@0 56
michael@0 57 // Ask the timer to use nsITimerCallback (.notify()) when ready
michael@0 58 this.timer_.initWithCallback(this, delayMS, type);
michael@0 59 }
michael@0 60
michael@0 61 /**
michael@0 62 * Cancel this timer
michael@0 63 */
michael@0 64 G_Alarm.prototype.cancel = function() {
michael@0 65 if (!this.timer_) {
michael@0 66 return;
michael@0 67 }
michael@0 68
michael@0 69 this.timer_.cancel();
michael@0 70 // Break circular reference created between this.timer_ and the G_Alarm
michael@0 71 // instance (this)
michael@0 72 this.timer_ = null;
michael@0 73 this.callback_ = null;
michael@0 74
michael@0 75 // We don't need the shutdown observer anymore
michael@0 76 this.observerServiceObserver_.unregister();
michael@0 77 }
michael@0 78
michael@0 79 /**
michael@0 80 * Invoked by the timer when it fires
michael@0 81 *
michael@0 82 * @param timer Reference to the nsITimer which fired (not currently
michael@0 83 * passed along)
michael@0 84 */
michael@0 85 G_Alarm.prototype.notify = function(timer) {
michael@0 86 // fire callback and save results
michael@0 87 var ret = this.callback_();
michael@0 88
michael@0 89 // If they've given us a max number of times to fire, enforce it
michael@0 90 this.nTimes_++;
michael@0 91 if (this.repeating_ &&
michael@0 92 typeof this.maxTimes_ == "number"
michael@0 93 && this.nTimes_ >= this.maxTimes_) {
michael@0 94 this.cancel();
michael@0 95 } else if (!this.repeating_) {
michael@0 96 // Clear out the callback closure for TYPE_ONE_SHOT timers
michael@0 97 this.cancel();
michael@0 98 }
michael@0 99 // We don't cancel/cleanup timers that repeat forever until either
michael@0 100 // xpcom-shutdown occurs or cancel() is called explicitly.
michael@0 101
michael@0 102 return ret;
michael@0 103 }
michael@0 104
michael@0 105 G_Alarm.prototype.setDelay = function(delay) {
michael@0 106 this.timer_.delay = delay;
michael@0 107 }
michael@0 108
michael@0 109 /**
michael@0 110 * XPCOM cruft
michael@0 111 */
michael@0 112 G_Alarm.prototype.QueryInterface = function(iid) {
michael@0 113 if (iid.equals(Components.interfaces.nsISupports) ||
michael@0 114 iid.equals(Components.interfaces.nsITimerCallback))
michael@0 115 return this;
michael@0 116
michael@0 117 throw Components.results.NS_ERROR_NO_INTERFACE;
michael@0 118 }
michael@0 119
michael@0 120
michael@0 121 /**
michael@0 122 * An alarm with the additional property that it cancels itself if its
michael@0 123 * callback returns true.
michael@0 124 *
michael@0 125 * For parameter documentation, see G_Alarm
michael@0 126 */
michael@0 127 function G_ConditionalAlarm(callback, delayMS, opt_repeating, opt_maxTimes) {
michael@0 128 G_Alarm.call(this, callback, delayMS, opt_repeating, opt_maxTimes);
michael@0 129 this.debugZone = "conditionalalarm";
michael@0 130 }
michael@0 131
michael@0 132 G_ConditionalAlarm.inherits(G_Alarm);
michael@0 133
michael@0 134 /**
michael@0 135 * Invoked by the timer when it fires
michael@0 136 *
michael@0 137 * @param timer Reference to the nsITimer which fired (not currently
michael@0 138 * passed along)
michael@0 139 */
michael@0 140 G_ConditionalAlarm.prototype.notify = function(timer) {
michael@0 141 // Call G_Alarm::notify
michael@0 142 var rv = G_Alarm.prototype.notify.call(this, timer);
michael@0 143
michael@0 144 if (this.repeating_ && rv) {
michael@0 145 G_Debug(this, "Callback of a repeating alarm returned true; cancelling.");
michael@0 146 this.cancel();
michael@0 147 }
michael@0 148 }

mercurial