Tuesday, March 11, 2008

Avoiding ThreadDeath with env.js

At Appcelerator we use John Resig's "simulated browser environment for Rhino" as part of our IDE. I'd had intermittent problems with a ThreadDeath error being thrown, which would then cause any other thread running Rhino to hang.



I wasn't sure if the problem was in my Java code, my JavaScript, Rhino's Java code, or Aptana's Java code (we built our IDE atop their HTML/CSS/JS editor). Turns out it wasn't any of those! It was in that "simulated browser environment" code, in window.clearInterval where the thread spawned with setInterval is killed. I puzzled for a moment over why Mr.Resig was using multiple threads rather than a single one for setIntervals (expediency I assume), and then changed two lines so that it doesn't kill the thread, but allows it to die of natural causes.


window.setInterval = function(fn, time){
var num = timers.length;

timers[num] = new java.lang.Thread(new java.lang.Runnable({
run: function(){
while (true) {
while (timers[num]) {
java.lang.Thread.currentThread().sleep(time);
fn();
}
}
}));

timers[num].start();

return num;
};

window.clearInterval = function(num){
if ( timers[num] ) {
timers[num].stop();
delete timers[num];
}
};


Another example of a day of debugging yielding a two line fix. Ugh.