Firefox shutdown is composed of phases that take place sequentially. Typically, each shutdown phase removes some capabilities from the application. For instance, at the end of phase profileBeforeChange, no service is permitted to write to the profile directory (with the exception of Telemetry). Consequently, if any service has requested I/O to the profile directory before or during phase profileBeforeChange, the system must be informed that these requests need to be completed before the end of phase profileBeforeChange. Failing to inform the system of this requirement can (and has been known to) cause data loss.
At some point during shutdown, the Add-On Manager needs to ensure that all add-ons have safely written their data to disk, before writing its own data. Since the data is saved to the profile, this must be completed during phase profileBeforeChange.
AsyncShutdown.profileBeforeChange.addBlocker( "Add-on manager: shutting down", function condition() { let promise = ... // Do whatever must be done before the end of phase profileBeforeChange return promise; }, function info() { let status = ... // Collect any information that may be useful for debugging shutdown issues with this blocker return status; } });
In this example, at some point during phase profileBeforeChange
, function condition
will be called. Phase profileBeforeChange
is guaranteed to not terminate until promise
is either resolved or rejected. If, for some reason, promise
is never resolved/rejected, Firefox will crash during shutdown to avoid blocking system shutdown, preventing the user from restarting Firefox or burning through a battery. In this case, a crash report is produced, with information on all the shutdown blockers that have not been resolved, and all the additional debug information returned by calls to info()
.
Note that you cannot create an instance of Phase yourself. See Attributes for the instances of Phase. If you need a new Phase added to AsyncShutdown, please file a bug.
void addBlocker(string name, function|promise condition, optional function info) |
boolean removeBlocker(function|promise condition) |
Register a blocker for the completion of a phase.
void addBlocker( in string name, in function|promise|* condition, optional in function info )
condition
is not a function but another value v
, it behaves as if it were a function returning v
.Remove the blocker for a condition.
If several blockers have been registered for the same condition, remove all these blockers. If no blocker has been registered for this condition, this is a noop.
boolean removeBlocker( in function|promise|* condition )
Returns true
if a blocker has been removed, or false
otherwise. Note that a result of false
may mean either that the blocker has never been installed or that the phase has completed and the blocker has already been resolved.
AsyncShutdown.profileBeforeChange.addBlocker("Module: just a promise", promise); // profileBeforeChange will not complete until // promise is resolved or rejected AsyncShutdown.profileBeforeChange.addBlocker("Module: a callback", function condition() { // ... // Execute this code during profileBeforeChange return promise; // profileBeforeChange will not complete until promise // is resolved or rejected }); AsyncShutdown.profileBeforeChange.addBlocker("Module: trivial callback", function condition() { // ... // Execute this code during profileBeforeChange // No specific guarantee about completion of profileBeforeChange });
If the promise returned by condition
is not resolved/rejected within one minute, the process will crash to avoid blocking system shutdown, preventing the user from restarting Firefox or burning through battery. This is by design. It is the caller's responsibility to ensure that the promise is eventually resolved/rejected.
Attribute | Type | Description |
|
Phase |
The profile is about to be unmounted. This phase represents the last chance to write data to the profile directory. |
sendTelemetry Read only |
Phase |
Telemetry is being sent. This phase represents the last chance for Telemetry to write data. |
webWorkersShutdown Read only |
Phase |
JavaScript threads are about to be killed. This phase represents the last chance to communicate with a JavaScript worker, in particular with OS.File. |