unsafe CPOW usage

Brad Lassey
blassey
Published in
2 min readJan 10, 2015

--

Cross Process Object Wrappers (aka CPOWs) are at the same time amazing and terrible. They are amazing in that they make things Just Work™ in Electrolysis (e10s). One of the major issues with converting Firefox code to work under e10s is chrome code that runs in the chrome process and would previously access content directly. Without CPOWs, this access would simply fail. With CPOWs in place, the code can carry on accessing these JavaScript objects that “live” in the content process. Having this mechanism in place has allowed us to have a working browser relatively quickly without the need to rewrite all of the code at once.

The trouble comes with the fact that in order to accomplish this magic, CPOWs send synchronous IPC messages to the content process. First of all, there is the general IPC overhead. Next, when you issue a synchronous IPC message from the chrome process, everything on the main thread of the chrome process comes to a complete stop until the content process gets around to handling that IPC message.

One of the scariest parts of CPOWs is that they allow synchronous messages to flow in both directions between the content and chrome processes. That kind of arrangement can be a recipe for deadlocks. We avoid them by forcing one side (the child) to process its incoming message while it waits for a response to its outgoing message. That has worked well so far. Other than some plugin-related issues that are solvable, we’re not aware of any CPOW-caused deadlocks in e10s right now (bugs are always possible of course). Unfortunately, performing this trick sometimes requires messages to be delivered in a different order than they were sent. In such situations, rather than deadlock or deliver messages out of order, we intentionally crash. Bug 1086684 is one example. We’ve been fixing these crashes on a case-by-case basis, but each one requires careful reasoning to fix.

There is, however, one circumstance where it is safe to do this, and that is while the chrome process is handling a synchronous message from the content process. In that circumstance, the content process is in a known good state and has nothing to do on the main thread other than handle the chrome process’s IPC messages. At this point the only downside is the IPC overhead.

So, with that context earlier this week I landed bug 1097998 which logs a warning to the console whenever CPOWs are used outside of this safe circumstance. Going forward we will be working to remove any instance of this unsafe usage from our code. Eventually, this may throw an exception (or some similar mechanism) to ensure we don’t regress.

--

--