nsITimer anti-pattern

I’ve filed bug 640629 to address an intermittent source of orange: incorrect nsITimer creation. I first ran across it while working on making httpd.js collect garbage more frequently, a task which quickly turned into orange whack-a-mole as more and more problematic test constructs popped out of the nether. Mounir Lamouri (volkmar) recently fixed another instance of the nsITimer problem, so I thought I’d address it in public and do some education.

When you see a construct like this, you should be wary:

function doSomething() {
  var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
  timer.initWithCallback(callback, delay, timer.TYPE_ONE_SHOT);

There’s a common misconception that timers retain an extra reference that is released after they fire. This is false. If a timer is created and stored in a locally-scoped variable and the scope is exited, the timer is at risk of being garbage-collected before the timer fires. To combat this, store a reference to the timer elsewhere – a member of an object that outlives the current scope, a global variable, it doesn’t matter. Do your part – save a timer’s life today.

3 Responses to “nsITimer anti-pattern”

  1. Yeah, that’s the one that almost everybody gets wrong. I don’t think that anybody expects the timer to be garbage-collected and the warning on MDC is easy to overlook.

  2. fabuleusa curas mi combar te ontri fario emeje. ouria te figodenta olvismo nos acliens o riameguis dotav empos bien.

  3. I think if you use the init() method, the observer reference holds the timer for you and this problem doesn’t occur.

Leave a Reply