Constellation manages script thread lifetime#14052
Conversation
|
Heads up! This PR modifies the following files:
|
9ac6e4d to
774172b
Compare
|
Rebased. |
nox
left a comment
There was a problem hiding this comment.
Could you write in the second commit message why switching to a set of documents was needed?
| self.offset = self.offset + 1; | ||
| result | ||
| } | ||
| } |
There was a problem hiding this comment.
Why do you need this iterator? We shouldn't use NodeList outside from other DOM stuff IMO, it's quite inefficient.
Also, this iterator continues to increment offset for nothing if self.nodes.Item(self.offset) returned None, and it doesn't provide a size hint so it's probably used inefficiently.
| }, | ||
| DevtoolScriptControlMsg::GetRootNode(id, reply) => | ||
| devtools::handle_get_root_node(&context, id, reply), | ||
| devtools::handle_get_root_node(&*documents, id, reply), |
There was a problem hiding this comment.
Nit: why is the * suddenly needed?
| pub struct ScriptChan { | ||
| chan: IpcSender<ConstellationControlMsg>, | ||
| dont_send_or_sync: PhantomData<Rc<()>>, | ||
| } |
There was a problem hiding this comment.
This seems quite dangerous to me. Could we not rely on Drop? What happens if that value is forgotten?
There was a problem hiding this comment.
I disagree that it seems dangerous, but I don't understand why it's needed. Whether it's Sync or not seems immaterial, since we just seem to care that ownership can't be transferred to some non-constellation thread. However, if it's only constructed via the new method and that only returns Rc, this seems to be redundant.
There was a problem hiding this comment.
The dont_send_or_sync isn't necessary, it's just there to make sure that any messages that are sent on this channel come from the constellation thread. I could just remove it.
774172b to
354501b
Compare
|
r? @jdm |
components/script/script_thread.rs
Outdated
| debug!("Exiting script thread."); | ||
|
|
||
| while let Some(pipeline_id) = self.incomplete_loads.borrow().iter().next().map(|load| load.pipeline_id) | ||
| .or_else(|| self.documents.borrow().iter().next().map(|doc| doc.global().pipeline_id())) |
There was a problem hiding this comment.
let mut pipelines = self.incomplete_loads.borrow().iter().map(|load| load.pipeline_id);
let mut pipelines = self.documents.borrow().iter().map(|doc| doc.global().pipeline_id()).zip(pipelines);
while let Some(pipeline_id) = pipelines.next() {Also, if we add the ability to iterate over the keys of the documents object, the second iterator becomes clearer.
There was a problem hiding this comment.
The problem is we can't have the iterator borrowed while we call handle_exit_pipeline_msg, since it mutably borrows self.documents and self.incomplete_loads.
There was a problem hiding this comment.
I'm actually surprised that this works as written, since calling iter() should cause a new iterator to be created every time...
There was a problem hiding this comment.
A more workable option is to create a vector from the original iterators and iterate over that.
There was a problem hiding this comment.
There is new iterator each time, but that's okay because handle_exit_pipeline_msg removes the entry, so we don't end up infinitely looping. We can just collect the iterators into a vector though, that is probably easier to read.
| pub fn send(&self, msg: ConstellationControlMsg) -> Result<(), IOError> { | ||
| self.chan.send(msg) | ||
| } | ||
| pub fn new(chan: IpcSender<ConstellationControlMsg>) -> ScriptChan { |
There was a problem hiding this comment.
Why not make this return Rc<ScriptChan>?
| pub struct ScriptChan { | ||
| chan: IpcSender<ConstellationControlMsg>, | ||
| dont_send_or_sync: PhantomData<Rc<()>>, | ||
| } |
There was a problem hiding this comment.
I disagree that it seems dangerous, but I don't understand why it's needed. Whether it's Sync or not seems immaterial, since we just seem to care that ownership can't be transferred to some non-constellation thread. However, if it's only constructed via the new method and that only returns Rc, this seems to be redundant.
|
☔ The latest upstream changes (presumably #14013) made this pull request unmergeable. Please resolve the merge conflicts. |
354501b to
7624ea7
Compare
|
Looks good! |
d27a481 to
08effa7
Compare
|
Squashed. @bors-servo r=jdm |
|
📌 Commit 08effa7 has been approved by |
08effa7 to
0e7ffaf
Compare
|
@bors-servo r=jdm |
|
📌 Commit 0e7ffaf has been approved by |
…-lifetime, r=jdm Constellation manages script thread lifetime <!-- Please describe your changes on the following line: --> Yet another step towards fixing #633... At the moment, script threads are responsible for killing themselves when they have no more pipelines to manage. This is fine right now, because script threads have a root pipeline: once it is closed, everything is closed. It's not fine once we fix #633 because there's a race condition where the constellation could kill the last pipeline in a script thread, then open a new one in the same script thread. We can't have the constellation block on the script thread, waiting to make sure a pipeline is created, since this could introduce deadlock. The easiest solution is to have the constellation manage the script thread lifetime: when the constellation discovers that a script thread is not managing any live pipelines, it closes the script thread, and updates its own state. Most of the commits are from #14013, its just "Script thread lifetime is now managed by the constellation." (9ac6e4d) that's new. cc @jdm @ConnorGBrewster --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes do not require tests because refactoring <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/14052) <!-- Reviewable:end -->
|
☀️ Test successful - arm32, arm64, linux-dev, linux-rel-css, linux-rel-wpt, mac-dev-unit, mac-rel-css, mac-rel-wpt1, mac-rel-wpt2, windows-dev |
Yet another step towards fixing #633...
At the moment, script threads are responsible for killing themselves when they have no more pipelines to manage. This is fine right now, because script threads have a root pipeline: once it is closed, everything is closed. It's not fine once we fix #633 because there's a race condition where the constellation could kill the last pipeline in a script thread, then open a new one in the same script thread.
We can't have the constellation block on the script thread, waiting to make sure a pipeline is created, since this could introduce deadlock. The easiest solution is to have the constellation manage the script thread lifetime: when the constellation discovers that a script thread is not managing any live pipelines, it closes the script thread, and updates its own state.
Most of the commits are from #14013, its just "Script thread lifetime is now managed by the constellation." (9ac6e4d) that's new.
cc @jdm @ConnorGBrewster
./mach build -ddoes not report any errors./mach test-tidydoes not report any errorsThis change is