Jetpack Processes

Jetpack processes are created by components that implement the nsIJetpackService interface, and their parent chrome process communicates with them via the nsIJetpack interface.

Note: The Jetpack service, provided by nsIJetpackService, is not included by default in Firefox 4. Prior to Firefox 12, it could be included in custom builds by using ENABLE_JETPACK_SERVICE at compile time. However, the service has been removed entirely as of Firefox 12.

These processes are relatively lightweight, do not have access to XPCOM, and can innately do little other than compute. Messaging facilities that allow them to communicate with their parent chrome process are the only means by which they can be endowed with any real power.

Note: The above statement is not currently true, as js-ctypes is now provided to Jetpack processes as of bug 588563. A mechanism to optionally disable this feature has been proposed in bug 614351.

Privileged APIs

When script is evaluated in a Jetpack process via a call to nsIJetpack.evalScript(), the script's global scope is endowed with the following privileged APIs:

sendMessage(aMessageName [, v1 [, v2 [, ...]]])
Similar to nsIJetpack.sendMessage(), this function asynchronously sends a message to the chrome process.
callMessage(aMessageName [, v1 [, v2 [, ...]]])
This function is like sendMessage() but sends the message synchronously. It returns an Array whose elements are the return values of each receiver in the chrome process that was triggered by the message.
registerReceiver(aMessageName, aReceiver)
Similar to nsIJetpack.registerReceiver(), this function registers a callback that is triggered when the chrome process sends a message with the given name.
unregisterReceiver(aMessageName, aReceiver)
Similar to nsIJetpack.unregisterReceiver(), this function unregisters a callback previously registered with registerReceiver().
unregisterReceivers(aMessageName)
Similar to nsIJetpack.unregisterReceivers(), this function unregisters all callbacks for the given message name.
createHandle()
Similar to nsIJetpack.createHandle(), this function creates a new handle and returns it.
createSandbox()
This creates a new JavaScript sandbox and returns its global scope. This global scope does not contain privileged APIs, or any non-standard JavaScript objects for that matter, though new globals can be endowed by simply attaching them to the global scope as properties.
evalInSandbox(aSandbox, aScript)
Evaluates the given script contents in the given sandbox's global scope. At minimum, JavaScript 1.8.1 is used. Individual lines of the form //@line 1 "foo.js" can be used to specify filename and line number information for debugging purposes.
gc()
Synchronously performs garbage collection.

Handles

Messages that communicate between the browser and jetpack process may contain only serializable (JSON) data and handles. A handle can be used to provide context for messages. Either the browser or the jetpack implementation may create one.

A handle keeps any arbitrary properties attached to it alive, but those properties are not transmitted across the process boundary. These arbitrary properties are the primary means through which context can be provided for messages; for instance, if the handle is meant to represent a network request, an XMLHttpRequest instance can be attached to the handle on the chrome process.

Because a handle's existence crosses process boundaries and cross-process garbage collection does not exist, the lifetime of a handle needs to be controlled manually by code. By default, a handle is rooted in the JavaScript interpreter's garbage collector, meaning that even if a process throws it away, it will not be garbage collected unless the other process explicitly does something to indicate that it is no longer needed. If that other process does not do something explicit and simply removes all references to it, the handle remains rooted yet unreachable in both processes and a memory leak is created.

To prevent such memory leaks, a process can either invalidate a handle, immediately preventing it from being passed as a message argument, or it can unroot the handle, allowing it to be passed as a message argument until all references to it are removed, at which point it is garbage collected.

Handles have the following native methods and properties:

invalidate()
Invalidates the handle. Either process may invalidate a handle when it is no longer useful.
createHandle()
Creates a child handle which becomes invalid when its parent does. This is useful for associating handles to the lifetime of a particular window, context menu, or other element, and helping ensure that they do not leak.
parent
The parent handle of the object, if any. Read-only.
isValid
Whether the handle is still valid or not. Read-only.
isRooted
Whether the handle is GC rooted or not. Read-write.
onInvalidate
A callback to call when the handle is garbage collected, either through an explicit call to invalidate() or being unrooted and then unreachable. The callback is only called from the process that the handle was not garbage collected in. Read-write.

Special Messages

core:process-error(context)
When the jetpack process crashes, this message is sent to the parent. If a crash report minidump is available, the context.dumpID property will list the minidump ID of the crash report that was collected.
core:exception(error)
When an exception occurs in a Jetpack script and is not caught, this message is sent to the parent. The error object contains the following properties: fileName, lineNumber, and message.

History

See bug 556846 and bug 578821 for details.

Sample Code

For example code, check out the unit tests.

See also