Bug 1118272 - Hold a cpu wakelock for async call "AlarmsManager.add". r=fabrice

This commit is contained in:
Henry Chang 2015-03-09 11:22:29 +08:00
parent b658f9d97e
commit d05811e3df

View File

@ -6,6 +6,7 @@
/* static functions */
const DEBUG = false;
const REQUEST_CPU_LOCK_TIMEOUT = 10 * 1000; // 10 seconds.
function debug(aStr) {
if (DEBUG)
@ -18,8 +19,15 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "gPowerManagerService",
"@mozilla.org/power/powermanagerservice;1",
"nsIPowerManagerService");
function AlarmsManager() {
debug("Constructor");
// A <requestId, {cpuLock, timer}> map.
this._cpuLockDict = new Map();
}
AlarmsManager.prototype = {
@ -71,8 +79,10 @@ AlarmsManager.prototype = {
data = JSON.parse(Cu.evalInSandbox("JSON.stringify(data)", sandbox));
}
let request = this.createRequest();
let requestId = this.getRequestId(request);
this._lockCpuForRequest(requestId);
this._cpmm.sendAsyncMessage("AlarmsManager:Add",
{ requestId: this.getRequestId(request),
{ requestId: requestId,
date: aDate,
ignoreTimezone: isIgnoreTimezone,
data: data,
@ -111,6 +121,7 @@ AlarmsManager.prototype = {
switch (aMessage.name) {
case "AlarmsManager:Add:Return:OK":
this._unlockCpuForRequest(json.requestId);
Services.DOMRequest.fireSuccess(request, json.id);
break;
@ -131,6 +142,7 @@ AlarmsManager.prototype = {
break;
case "AlarmsManager:Add:Return:KO":
this._unlockCpuForRequest(json.requestId);
Services.DOMRequest.fireError(request, json.errorMsg);
break;
@ -172,6 +184,44 @@ AlarmsManager.prototype = {
uninit: function uninit() {
debug("uninit()");
},
_lockCpuForRequest: function (aRequestId) {
if (this._cpuLockDict.has(aRequestId)) {
debug('Cpu wakelock for request ' + aRequestId + ' has been acquired. ' +
'You may call this function repeatedly or requestId is collision.');
return;
}
// Acquire a lock for given request and save for lookup lately.
debug('Acquire cpu lock for request ' + aRequestId);
let cpuLockInfo = {
cpuLock: gPowerManagerService.newWakeLock("cpu"),
timer: Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer)
};
this._cpuLockDict.set(aRequestId, cpuLockInfo);
// Start a timer to prevent from non-responding request.
cpuLockInfo.timer.initWithCallback(() => {
debug('Request timeout! Release the cpu lock');
this._unlockCpuForRequest(aRequestId);
}, REQUEST_CPU_LOCK_TIMEOUT, Ci.nsITimer.TYPE_ONE_SHOT);
},
_unlockCpuForRequest: function(aRequestId) {
let cpuLockInfo = this._cpuLockDict.get(aRequestId);
if (!cpuLockInfo) {
debug('The cpu lock for requestId ' + aRequestId + ' is either invalid ' +
'or has been released.');
return;
}
// Release the cpu lock and cancel the timer.
debug('Release the cpu lock for ' + aRequestId);
cpuLockInfo.cpuLock.unlock();
cpuLockInfo.timer.cancel();
this._cpuLockDict.delete(aRequestId);
},
}
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([AlarmsManager])