Bug 980549 - 'Intermittently unable to unlock lock screen'. r=gwagner.

This commit is contained in:
Ben Turner 2014-04-14 17:40:00 -07:00
Родитель 161f5277d2
Коммит 20542b9af5
2 изменённых файлов: 44 добавлений и 37 удалений

Просмотреть файл

@ -19,9 +19,11 @@ const Ci = Components.interfaces;
this.EXPORTED_SYMBOLS = ["IndexedDBHelper"];
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.importGlobalProperties(["indexedDB"]);
XPCOMUtils.defineLazyModuleGetter(this, 'Services',
'resource://gre/modules/Services.jsm');
this.IndexedDBHelper = function IndexedDBHelper() {}
IndexedDBHelper.prototype = {
@ -88,7 +90,10 @@ IndexedDBHelper.prototype = {
ensureDB: function ensureDB(aSuccessCb, aFailureCb) {
if (this._db) {
if (DEBUG) debug("ensureDB: already have a database, returning early.");
aSuccessCb && aSuccessCb();
if (aSuccessCb) {
Services.tm.currentThread.dispatch(aSuccessCb,
Ci.nsIThread.DISPATCH_NORMAL);
}
return;
}
this.open(aSuccessCb, aFailureCb);

Просмотреть файл

@ -32,6 +32,13 @@ function SettingsLock(aSettingsManager) {
this._requests = new Queue();
this._settingsManager = aSettingsManager;
this._transaction = null;
let closeHelper = function() {
if (DEBUG) debug("closing lock");
this._open = false;
}.bind(this);
Services.tm.currentThread.dispatch(closeHelper, Ci.nsIThread.DISPATCH_NORMAL);
}
SettingsLock.prototype = {
@ -65,11 +72,13 @@ SettingsLock.prototype = {
break;
case "set":
let keys = Object.getOwnPropertyNames(info.settings);
if (keys.length) {
lock._isBusy = true;
}
for (let i = 0; i < keys.length; i++) {
let key = keys[i];
let last = i === keys.length - 1;
if (DEBUG) debug("key: " + key + ", val: " + JSON.stringify(info.settings[key]) + ", type: " + typeof(info.settings[key]));
lock._isBusy = true;
let checkKeyRequest = store.get(key);
checkKeyRequest.onsuccess = function (event) {
@ -87,15 +96,11 @@ SettingsLock.prototype = {
let setReq = store.put(obj);
setReq.onsuccess = function() {
lock._isBusy = false;
cpmm.sendAsyncMessage("Settings:Changed", { key: key, value: userValue });
if (last && !request.error) {
lock._open = true;
Services.DOMRequest.fireSuccess(request, 0);
lock._open = false;
if (!lock._requests.isEmpty()) {
lock.process();
}
}
};
@ -104,6 +109,13 @@ SettingsLock.prototype = {
Services.DOMRequest.fireError(request, setReq.error.name)
}
};
if (last) {
lock._isBusy = false;
if (!lock._requests.isEmpty()) {
lock.process();
}
}
};
checkKeyRequest.onerror = function(event) {
if (!request.error) {
@ -111,7 +123,9 @@ SettingsLock.prototype = {
}
};
}
break;
// Don't break here, instead return. Once the previous requests have
// finished this loop will start again.
return;
case "get":
let getReq = (info.name === "*") ? store.mozGetAll()
: store.mozGetAll(info.name);
@ -148,22 +162,20 @@ SettingsLock.prototype = {
},
createTransactionAndProcess: function() {
if (this._settingsManager._settingsDB._db) {
var lock;
while (lock = this._settingsManager._locks.dequeue()) {
if (!lock._transaction) {
let transactionType = this._settingsManager.hasWritePrivileges ? "readwrite" : "readonly";
lock._transaction = lock._settingsManager._settingsDB._db.transaction(SETTINGSSTORE_NAME, transactionType);
}
if (!lock._isBusy) {
lock.process();
} else {
this._settingsManager._locks.enqueue(lock);
}
}
if (!this._requests.isEmpty() && !this._isBusy) {
this.process();
}
if (DEBUG) debug("database opened, creating transaction");
let manager = this._settingsManager;
let transactionType = manager.hasWritePrivileges ? "readwrite" : "readonly";
this._transaction =
manager._settingsDB._db.transaction(SETTINGSSTORE_NAME, transactionType);
this.process();
},
maybeProcess: function() {
if (this._transaction && !this._isBusy) {
this.process();
}
},
@ -176,7 +188,7 @@ SettingsLock.prototype = {
if (this._settingsManager.hasReadPrivileges) {
let req = Services.DOMRequest.createRequest(this._settingsManager._window);
this._requests.enqueue({ request: req, intent:"get", name: aName });
this.createTransactionAndProcess();
this.maybeProcess();
return req;
} else {
if (DEBUG) debug("get not allowed");
@ -221,7 +233,7 @@ SettingsLock.prototype = {
if (DEBUG) debug("send: " + JSON.stringify(aSettings));
let settings = this._serializePreservingBinaries(aSettings);
this._requests.enqueue({request: req, intent: "set", settings: settings});
this.createTransactionAndProcess();
this.maybeProcess();
return req;
} else {
if (DEBUG) debug("set not allowed");
@ -237,7 +249,7 @@ SettingsLock.prototype = {
if (this._settingsManager.hasWritePrivileges) {
let req = Services.DOMRequest.createRequest(this._settingsManager._window);
this._requests.enqueue({ request: req, intent: "clear"});
this.createTransactionAndProcess();
this.maybeProcess();
return req;
} else {
if (DEBUG) debug("clear not allowed");
@ -251,7 +263,6 @@ SettingsLock.prototype = {
};
function SettingsManager() {
this._locks = new Queue();
this._settingsDB = new SettingsDB();
this._settingsDB.init();
}
@ -263,13 +274,6 @@ SettingsManager.prototype = {
return Cu.cloneInto(obj, this._window);
},
nextTick: function nextTick(aCallback, thisObj) {
if (thisObj)
aCallback = aCallback.bind(thisObj);
Services.tm.currentThread.dispatch(aCallback, Ci.nsIThread.DISPATCH_NORMAL);
},
set onsettingchange(aHandler) {
this.__DOM_IMPL__.setEventHandler("onsettingchange", aHandler);
},
@ -281,12 +285,10 @@ SettingsManager.prototype = {
createLock: function() {
if (DEBUG) debug("get lock!");
var lock = new SettingsLock(this);
this._locks.enqueue(lock);
this._settingsDB.ensureDB(
function() { lock.createTransactionAndProcess(); },
function() { dump("Cannot open Settings DB. Trying to open an old version?\n"); }
);
this.nextTick(function() { this._open = false; }, lock);
return lock;
},