auto merge of #1415 : dhedlund/servo/constellation_deadlock, r=pcwalton

Constellation blocks on SetId by sending a Port through the compositor channel and waits for a response.  If the compositor is in the process of shutting down, it will not look in the queue again.  The compositor requires the constellation to be shut down first, so it sends a message to shut down and blocks until the constellation finishes, deadlocking.

Only very short lived executions would've been likely to see this deadlock.

_It is technically still possible to trigger a SetId message between when the compositor finishes running and when the constellation shuts down, but the window for exposure is greatly reduced.  I've only seen it with "-o" so far._
This commit is contained in:
bors-servo 2013-12-15 11:25:26 -08:00
commit b81749bee3
2 changed files with 11 additions and 3 deletions

View file

@ -426,4 +426,8 @@ pub fn run_compositor(compositor: &CompositorTask) {
None => {}
Some(ref mut layer) => layer.forget_all_tiles(),
}
// Drain compositor port, sometimes messages contain channels that are blocking
// another task from finishing (i.e. SetIds)
while compositor.port.peek() { compositor.port.recv(); }
}

View file

@ -807,9 +807,13 @@ impl Constellation {
fn set_ids(&self, frame_tree: @mut FrameTree) {
let (port, chan) = comm::stream();
self.compositor_chan.send(SetIds(frame_tree.to_sendable(), chan, self.chan.clone()));
port.try_recv();
for frame in frame_tree.iter() {
frame.pipeline.grant_paint_permission();
match port.try_recv() {
Some(()) => {
for frame in frame_tree.iter() {
frame.pipeline.grant_paint_permission();
}
}
None => {} // message has been discarded, probably shutting down
}
}
}