Bug 701060 - Fix race condition with pref observers causing test orange. r=ehsan.

This commit is contained in:
Jonathan Watt 2012-01-27 22:16:44 +00:00
parent ce6420700a
commit 37c1301be5
3 changed files with 27 additions and 6 deletions

View File

@ -31,7 +31,7 @@ SimpleTest.waitForExplicitFinish();
var cs1 = getComputedStyle(document.getElementById("one"), "");
var cs2 = getComputedStyle(document.getElementById("two"), "");
SpecialPowers.pushPrefEnv({'set': [['variable.x-western', 25], ['fixed.x-western', 20]]}, function() setTimeout(part1, 0));
SpecialPowers.pushPrefEnv({'set': [['variable.x-western', 25], ['fixed.x-western', 20]]}, part1);
function part1()
{

View File

@ -56,7 +56,7 @@ function fs(idx) {
return getComputedStyle(elts[idx], "").marginBottom;
}
SpecialPowers.pushPrefEnv({'clear': [['font.minimum-size.x-western']]}, function() setTimeout(step1, 0));
SpecialPowers.pushPrefEnv({'clear': [['font.minimum-size.x-western']]}, step1);
function step1() {
is(fs(0), "0px", "at min font size 0, 0px should compute to 0px");
@ -64,7 +64,7 @@ function step1() {
is(fs(2), "12px", "at min font size 0, 12px should compute to 12px");
is(fs(3), "28px", "at min font size 0, 28px should compute to 28px");
SpecialPowers.pushPrefEnv({'set': [['font.minimum-size.x-western', 7]]}, function() setTimeout(step2, 0));
SpecialPowers.pushPrefEnv({'set': [['font.minimum-size.x-western', 7]]}, step2);
}
function step2() {
@ -73,7 +73,7 @@ function step2() {
is(fs(2), "12px", "at min font size 7, 12px should compute to 12px");
is(fs(3), "28px", "at min font size 7, 28px should compute to 28px");
SpecialPowers.pushPrefEnv({'set': [['font.minimum-size.x-western', 18]]}, function() setTimeout(step3, 0));
SpecialPowers.pushPrefEnv({'set': [['font.minimum-size.x-western', 18]]}, step3);
}
function step3() {

View File

@ -546,8 +546,21 @@ SpecialPowersAPI.prototype = {
}
if (pendingActions.length > 0) {
// The callback needs to be delayed twice. One delay is because the pref
// service doesn't guarantee the order it calls its observers in, so it
// may notify the observer holding the callback before the other
// observers have been notified and given a chance to make the changes
// that the callback checks for. The second delay is because pref
// observers often defer making their changes by posting an event to the
// event loop.
function delayedCallback() {
function delayAgain() {
content.window.setTimeout(callback, 0);
}
content.window.setTimeout(delayAgain, 0);
}
this._prefEnvUndoStack.push(cleanupActions);
this._pendingPrefs.push([pendingActions, callback]);
this._pendingPrefs.push([pendingActions, delayedCallback]);
this._applyPrefs();
} else {
content.window.setTimeout(callback, 0);
@ -556,8 +569,16 @@ SpecialPowersAPI.prototype = {
popPrefEnv: function(callback) {
if (this._prefEnvUndoStack.length > 0) {
// See pushPrefEnv comment regarding delay.
function delayedCallback() {
function delayAgain() {
content.window.setTimeout(callback, 0);
}
content.window.setTimeout(delayAgain, 0);
}
let cb = callback ? delayedCallback : null;
/* Each pop will have a valid block of preferences */
this._pendingPrefs.push([this._prefEnvUndoStack.pop(), callback]);
this._pendingPrefs.push([this._prefEnvUndoStack.pop(), cb]);
this._applyPrefs();
} else {
content.window.setTimeout(callback, 0);