Drain compositor_chan on shutdown, causes deadlocks on constellation

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.
This commit is contained in:
Daniel Hedlund 2013-12-14 21:35:33 -08:00
parent c5d81f13c1
commit 183c387d8b
2 changed files with 11 additions and 3 deletions

View file

@ -421,4 +421,8 @@ pub fn run_compositor(compositor: &CompositorTask) {
None => {} None => {}
Some(ref mut layer) => layer.forget_all_tiles(), 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) { fn set_ids(&self, frame_tree: @mut FrameTree) {
let (port, chan) = comm::stream(); let (port, chan) = comm::stream();
self.compositor_chan.send(SetIds(frame_tree.to_sendable(), chan, self.chan.clone())); self.compositor_chan.send(SetIds(frame_tree.to_sendable(), chan, self.chan.clone()));
port.try_recv(); match port.try_recv() {
for frame in frame_tree.iter() { Some(()) => {
frame.pipeline.grant_paint_permission(); for frame in frame_tree.iter() {
frame.pipeline.grant_paint_permission();
}
}
None => {} // message has been discarded, probably shutting down
} }
} }
} }