Bug 995162 - Rewrite the mechanism that (re)starts the OS.File worker. r=froydnj

This commit is contained in:
David Rajchenbach-Teller 2014-04-16 17:04:47 -04:00
parent 2672ecf027
commit b92fc7f93b
2 changed files with 45 additions and 17 deletions

View File

@ -179,8 +179,8 @@ function summarizeObject(obj) {
return obj;
}
let worker = null;
let Scheduler = {
/**
* |true| once we have sent at least one message to the worker.
* This field is unaffected by resetting the worker.
@ -237,6 +237,25 @@ let Scheduler = {
*/
resetTimer: null,
/**
* The worker to which to send requests.
*
* If the worker has never been created or has been reset, this is a
* fresh worker, initialized with osfile_async_worker.js.
*
* @type {PromiseWorker}
*/
get worker() {
if (!this._worker) {
// Either the worker has never been created or it has been reset
this._worker = new PromiseWorker(
"resource://gre/modules/osfile/osfile_async_worker.js", LOG);
}
return this._worker;
},
_worker: null,
/**
* Prepare to kill the OS.File worker after a few seconds.
*/
@ -273,10 +292,14 @@ let Scheduler = {
yield this.queue;
if (!this.launched || this.shutdown || !worker) {
// Enter critical section: no yield in this block
// (we want to make sure that we remain the only
// request in the queue).
if (!this.launched || this.shutdown || !this._worker) {
// Nothing to kill
this.shutdown = this.shutdown || shutdown;
worker = null;
this._worker = null;
return null;
}
@ -285,12 +308,15 @@ let Scheduler = {
let deferred = Promise.defer();
this.queue = deferred.promise;
// Exit critical section
let message = ["Meta_shutdown", [reset]];
try {
Scheduler.latestReceived = [];
Scheduler.latestSent = [Date.now(), ...message];
let promise = worker.post(...message);
let promise = this._worker.post(...message);
// Wait for result
let resources;
@ -329,7 +355,7 @@ let Scheduler = {
// Make sure that we do not leave an invalid |worker| around.
if (killed || shutdown) {
worker = null;
this._worker = null;
}
this.shutdown = shutdown;
@ -376,19 +402,14 @@ let Scheduler = {
if (this.shutdown) {
LOG("OS.File is not available anymore. The following request has been rejected.",
method, args);
return Promise.reject(new Error("OS.File has been shut down."));
}
if (!worker) {
// Either the worker has never been created or it has been reset
worker = new PromiseWorker(
"resource://gre/modules/osfile/osfile_async_worker.js", LOG);
return Promise.reject(new Error("OS.File has been shut down. Rejecting post to " + method));
}
let firstLaunch = !this.launched;
this.launched = true;
if (firstLaunch && SharedAll.Config.DEBUG) {
// If we have delayed sending SET_DEBUG, do it now.
worker.post("SET_DEBUG", [true]);
this.worker.post("SET_DEBUG", [true]);
Scheduler.Debugging.messagesSent++;
}
@ -399,7 +420,13 @@ let Scheduler = {
options = methodArgs[methodArgs.length - 1];
}
Scheduler.Debugging.messagesQueued++;
return this.push(() => Task.spawn(function*() {
return this.push(Task.async(function*() {
if (this.shutdown) {
LOG("OS.File is not available anymore. The following request has been rejected.",
method, args);
throw new Error("OS.File has been shut down. Rejecting request to " + method);
}
// Update debugging information. As |args| may be quite
// expensive, we only keep a shortened version of it.
Scheduler.Debugging.latestReceived = null;
@ -414,7 +441,7 @@ let Scheduler = {
let isError = false;
try {
try {
data = yield worker.post(method, ...args);
data = yield this.worker.post(method, ...args);
} finally {
Scheduler.Debugging.messagesReceived++;
}
@ -474,7 +501,7 @@ let Scheduler = {
options.outExecutionDuration = durationMs;
}
return data.ok;
}));
}.bind(this)));
},
/**
@ -483,6 +510,7 @@ let Scheduler = {
* This is only useful on first launch.
*/
_updateTelemetry: function() {
let worker = this.worker;
let workerTimeStamps = worker.workerTimeStamps;
if (!workerTimeStamps) {
// If the first call to OS.File results in an uncaught errors,
@ -1482,7 +1510,7 @@ AsyncShutdown.profileBeforeChange.addBlocker(
let result = {
launched: Scheduler.launched,
shutdown: Scheduler.shutdown,
worker: !!worker,
worker: !!Scheduler._worker,
pendingReset: !!Scheduler.resetTimer,
latestSent: Scheduler.Debugging.latestSent,
latestReceived: Scheduler.Debugging.latestReceived,

View File

@ -81,7 +81,7 @@ const EXCEPTION_NAMES = {
LOG("Method", method, "succeeded");
} catch (ex) {
exn = ex;
LOG("Error while calling agent method", exn, exn.stack || "");
LOG("Error while calling agent method", exn, exn.moduleStack || exn.stack || "");
}
if (start) {