All new code written in Gecko today is designed to be e10s ready. PBackground exists to solve some common problems that arise when writing e10s aware code which involves multiple threads in the chrome process. But before we dive into that, some background:

What is IPDL?

IPDL is a language used to define “protocols”, essentially formalized versions of how two things can communicate. It is similar in some respects to IDL and WebIDL. At build time the IPDL compiler automatically generates a large amount of C++ glue code from the IPDL files. IPDL protocols are used to specify how the chrome and content processes talk to each other and verify that a content process is “following the rules” so to speak. When used at run time, every protocol has two “actors”, a parent and a child. These actors can live in different processes, and IPDL automatically serializes calls on one side and transmits them to the other side. This is the foundation of how chrome and content processes talk to each other in e10s.

The actor tree

All live actors exist in a tree. The root of the tree is known as the top-level actor, and it is an instance of one of a small number of top-level protocols. All actors in a tree “live” on the same thread, and can only be used safely from that thread. The top-level actor for most things is PContent, which connects the main thread of the chrome process to the main thread of a child process. For most things this is great, because the DOM is already bound to the main thread. But in some cases we don’t necessarily want to talk to the main thread.

What if I want to talk to a different thread?

Not every communication between the chrome and content processes necessarily wants to go through the main threads of both (or even either) processes. When we are uploading textures from the content process we don’t need to go through the main thread of the parent process. Instead we can go directly to the compositor thread in the parent process by creating a new top-level protocol that connects the compositor thread in the parent process to the main thread of a child process. This protocol is called PCompositor. Using PCompositor allows us to bypass the main thread of the parent process, which trims the latency of texture uploads since they will not get bogged down if that thread is busy.

Writing code that works in both chrome and content processes



A lot of code “just works” in the content process. But some things, such as APIs that need to manipulate files, or device settings (e.g. geolocation) cannot run in the content process because it has restricted privileges. Instead these APIs must ask the chrome process to do something on their behalf via an IPDL protocol. In some parts of Mozilla this has lead to a rather awkward pattern like so:

if (XRE_GetProcessType() == GeckoProcessType_Default) { DoTheThing(arguments);

} else { mIPDLProtocol->SendDoTheThing(arguments);

}

This can get unwieldy.

PBackground

PBackground exists to solve both of these problems. It connects a designated “background” thread in the chrome process to any other thread in any process. PBackground

allows bypassing the chrome process’s main thread if used from the content process’s main thread.

allows bypassing both main threads if used from a non-main thread in a content process

allows writing process agnostic code because it can be used even from another thread in the parent process

The “parent” side of a PBackground actor pair is always on the designated background thread, while the child side is on the thread that chooses to use PBackground. The background thread is designed to be responsive (nobody is allowed to do long running computation or file I/O on it) to guarantee better latency than going through the main threads (which can run arbitrary JS, GC, etc) can provide.

Examples

IndexedDB was rebuilt on top of PBackground last year. This allows the DOM code to generally not worry about what thread (main vs. worker) or process (single vs. multiple) it is running in. Instead it simply turns all of its operations into IPDL calls on a set of PBackground based actors and the processing, file I/O, etc, can be controlled from the PBackground thread regardless of where the DOM calls are being made. The logic is all implemented in ActorsParent.cpp and ActorsChild.cpp in the dom/indexedDB folder. These are not small files (ActorsParent.cpp is 27k lines of code as of this writing!) but the logic that needs to run in the parent is very clearly separated from the DOM code no matter what thread it’s running on.

