/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ /** * A mechanism for specifying shutdown dependencies between * asynchronous services. * * Note that this XPCOM component is designed primarily for C++ * clients. JavaScript clients should rather use AsyncShutdown.sys.mjs, * which provides a better API and better error reporting for them. */ #include "nsISupports.idl" #include "nsIPropertyBag.idl" #include "nsIVariant.idl" interface nsIAsyncShutdownClient; /** * A blocker installed by a client to be informed during some stage of * shutdown and block shutdown asynchronously until some condition is * complete. * * If you wish to use AsyncShutdown, you will need to implement this * interface (and only this interface). */ [scriptable, uuid(4ef43f29-6715-4b57-a750-2ff83695ddce)] interface nsIAsyncShutdownBlocker: nsISupports { /** * The *unique* name of the blocker. * * By convention, it should respect the following format: * "MyModuleName: Doing something while it's time" * e.g. * "OS.File: Flushing before profile-before-change" * * This attribute is uploaded as part of crash reports. */ readonly attribute AString name; /** * Inform the blocker that the stage of shutdown has started. * Shutdown will NOT proceed until `aBarrierClient.removeBlocker(this)` * has been called. */ void blockShutdown(in nsIAsyncShutdownClient aBarrierClient); /** * The current state of the blocker. * * In case of crash, this is converted to JSON and attached to * the crash report. * * This field may be used to provide JSON-style data structures. * For this purpose, use * - nsIPropertyBag to represent objects; * - nsIVariant to represent field values (which may hold nsIPropertyBag * themselves). */ readonly attribute nsIPropertyBag state; }; /** * A client for a nsIAsyncShutdownBarrier. */ [scriptable, uuid(d2031049-b990-43a2-95be-59f8a3ca5954)] interface nsIAsyncShutdownClient: nsISupports { /** * The name of the barrier. */ readonly attribute AString name; /** * Whether the client is still open for new blockers. * When this is true it is too late to add new blockers and addBlocker will * throw an exception. */ readonly attribute boolean isClosed; /** * Add a blocker. * * After a `blocker` has been added with `addBlocker`, if it is not * removed with `removeBlocker`, this will, by design, eventually * CAUSE A CRASH. * * Calling `addBlocker` once nsIAsyncShutdownBarrier::wait() has been * called on the owning barrier returns an error. * * @param aBlocker The blocker to add. Once * nsIAsyncShutdownBarrier::wait() has been called, it will not * call its `aOnReady` callback until all blockers have been * removed, each by a call to `removeBlocker`. * @param aFileName The filename of the callsite, as given by `__FILE__`. * @param aLineNumber The linenumber of the callsite, as given by `__LINE__`. * @param aStack Information on the stack that lead to this call. Generally * empty when called from C++. * @throws If it's too late to add a blocker. * @see isClosed. */ void addBlocker(in nsIAsyncShutdownBlocker aBlocker, in AString aFileName, in long aLineNumber, in AString aStack); /** * Remove a blocker. * * @param aBlocker A blocker previously added to this client through * `addBlocker`. Noop if the blocker has never been added or has been * removed already. */ void removeBlocker(in nsIAsyncShutdownBlocker aBlocker); /** * The JS implementation of the client. * * It is strongly recommended that JS clients of this API use * `jsclient` instead of the `nsIAsyncShutdownClient`. See * AsyncShutdown.sys.mjs for more information on the JS version of * this API. */ readonly attribute jsval jsclient; }; /** * Callback invoked once all blockers of a barrier have been removed. */ [scriptable, function, uuid(910c9309-1da0-4dd0-8bdb-a325a38c604e)] interface nsIAsyncShutdownCompletionCallback: nsISupports { /** * The operation has been completed. */ void done(); }; /** * A stage of shutdown that supports blocker registration. */ [scriptable, uuid(50fa8a86-9c91-4256-8389-17d310adec90)] interface nsIAsyncShutdownBarrier: nsISupports { /** * The blocker registration capability. Most services may wish to * publish this capability to let services that depend on it register * blockers. */ readonly attribute nsIAsyncShutdownClient client; /** * The state of all the blockers of the barrier. * * See the documentation of `nsIAsyncShutdownBlocker` for the * format. */ readonly attribute nsIPropertyBag state; /** * Wait for all blockers to complete. * * Method `aOnReady` will be called once all blockers have finished. * The callback always receives NS_OK. */ void wait(in nsIAsyncShutdownCompletionCallback aOnReady); }; /** * A service that allows registering shutdown-time dependencies. */ [scriptable, uuid(db365c78-c860-4e64-9a63-25b73f89a016)] interface nsIAsyncShutdownService: nsISupports { /** * Create a new barrier. * * By convention, the name should respect the following format: * "MyModuleName: Doing something while it's time" * e.g. * "OS.File: Waiting for clients to flush before shutting down" * * This attribute is uploaded as part of crash reports. */ nsIAsyncShutdownBarrier makeBarrier(in AString aName); // Barriers for global shutdown stages in the parent process. /** * Barrier for notification profile-before-change. */ readonly attribute nsIAsyncShutdownClient profileBeforeChange; /** * Barrier for notification profile-change-teardown. */ readonly attribute nsIAsyncShutdownClient profileChangeTeardown; /** * Barrier for notification quit-application-granted. */ readonly attribute nsIAsyncShutdownClient quitApplicationGranted; /** * Barrier for notification profile-before-change-telemetry. */ readonly attribute nsIAsyncShutdownClient sendTelemetry; // Barriers for global shutdown stages in all processes. /** * Barrier for notification web-workers-shutdown. */ readonly attribute nsIAsyncShutdownClient webWorkersShutdown; /** * Barrier for notification xpcom-will-shutdown. */ readonly attribute nsIAsyncShutdownClient xpcomWillShutdown; // Don't add a barrier for content-child-shutdown because this // makes it easier to cause shutdown hangs. }; %{C++ #define NS_ASYNCSHUTDOWNSERVICE_CONTRACTID "@mozilla.org/async-shutdown-service;1" %}