mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
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:
commit
b81749bee3
2 changed files with 11 additions and 3 deletions
|
@ -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(); }
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue