Skip to content

Constellation manages script thread lifetime#14052

Merged
bors-servo merged 1 commit intoservo:masterfrom
asajeffrey:constellation-manages-script-thread-lifetime
Nov 9, 2016
Merged

Constellation manages script thread lifetime#14052
bors-servo merged 1 commit intoservo:masterfrom
asajeffrey:constellation-manages-script-thread-lifetime

Conversation

@asajeffrey
Copy link
Copy Markdown
Contributor

@asajeffrey asajeffrey commented Nov 3, 2016

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 -d does not report any errors
  • ./mach test-tidy does not report any errors
  • These changes do not require tests because refactoring

This change is Reviewable

@asajeffrey asajeffrey added I-refactor No impact; the issue is one of maintainability or tidiness. Proposed solution requires refactoring. A-content/script Related to the script thread A-constellation Involves the constellation labels Nov 3, 2016
@highfive
Copy link
Copy Markdown

highfive commented Nov 3, 2016

Heads up! This PR modifies the following files:

  • @fitzgen: components/script/dom/htmliframeelement.rs, components/script/dom/document.rs, components/script/webdriver_handlers.rs, components/script/dom/node.rs, components/script/dom/browsingcontext.rs, components/script/dom/storage.rs, components/script_traits/script_msg.rs, components/script_traits/script_msg.rs, components/script/document_loader.rs, components/script/dom/nodelist.rs, components/script/script_thread.rs, components/script_traits/lib.rs, components/script_traits/lib.rs, components/script/devtools.rs
  • @KiChjang: components/script/dom/htmliframeelement.rs, components/script/dom/document.rs, components/script/webdriver_handlers.rs, components/net/http_loader.rs, components/script/dom/node.rs, components/script/dom/browsingcontext.rs, components/script/dom/storage.rs, components/script_traits/script_msg.rs, components/script_traits/script_msg.rs, components/script/document_loader.rs, components/script/dom/nodelist.rs, components/script/script_thread.rs, components/script_traits/lib.rs, components/script_traits/lib.rs, components/script/devtools.rs

@highfive
Copy link
Copy Markdown

highfive commented Nov 3, 2016

warning Warning warning

  • These commits modify unsafe code. Please review it carefully!

@highfive highfive added the S-awaiting-review There is new code that needs to be reviewed. label Nov 3, 2016
@asajeffrey asajeffrey force-pushed the constellation-manages-script-thread-lifetime branch from 9ac6e4d to 774172b Compare November 3, 2016 21:09
@asajeffrey
Copy link
Copy Markdown
Contributor Author

Rebased.

Copy link
Copy Markdown
Contributor

@nox nox left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you write in the second commit message why switching to a set of documents was needed?

self.offset = self.offset + 1;
result
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: why is the * suddenly needed?

pub struct ScriptChan {
chan: IpcSender<ConstellationControlMsg>,
dont_send_or_sync: PhantomData<Rc<()>>,
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems quite dangerous to me. Could we not rely on Drop? What happens if that value is forgotten?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@asajeffrey
Copy link
Copy Markdown
Contributor Author

@nox: are you commenting on the changes in #14013? This PR is just the last commit. I love dependent PRs, I love dependent PRs...

@asajeffrey asajeffrey force-pushed the constellation-manages-script-thread-lifetime branch from 774172b to 354501b Compare November 4, 2016 14:30
@asajeffrey asajeffrey added the S-blocked-on-external Something, somewhere else, needs to happen before this PR can be merged. label Nov 4, 2016
@nox
Copy link
Copy Markdown
Contributor

nox commented Nov 4, 2016

r? @jdm

@highfive highfive assigned jdm and unassigned nox Nov 4, 2016
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()))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm actually surprised that this works as written, since calling iter() should cause a new iterator to be created every time...

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A more workable option is to create a vector from the original iterators and iterate over that.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not make this return Rc<ScriptChan>?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

pub struct ScriptChan {
chan: IpcSender<ConstellationControlMsg>,
dont_send_or_sync: PhantomData<Rc<()>>,
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@jdm jdm added S-needs-code-changes Changes have not yet been made that were requested by a reviewer. and removed S-awaiting-review There is new code that needs to be reviewed. labels Nov 7, 2016
@bors-servo
Copy link
Copy Markdown
Contributor

☔ The latest upstream changes (presumably #14013) made this pull request unmergeable. Please resolve the merge conflicts.

@highfive highfive added the S-needs-rebase There are merge conflict errors. label Nov 8, 2016
@asajeffrey asajeffrey force-pushed the constellation-manages-script-thread-lifetime branch from 354501b to 7624ea7 Compare November 8, 2016 18:42
@highfive highfive added S-awaiting-review There is new code that needs to be reviewed. and removed S-needs-code-changes Changes have not yet been made that were requested by a reviewer. labels Nov 8, 2016
@asajeffrey asajeffrey added S-needs-code-changes Changes have not yet been made that were requested by a reviewer. and removed S-awaiting-review There is new code that needs to be reviewed. S-blocked-on-external Something, somewhere else, needs to happen before this PR can be merged. S-needs-rebase There are merge conflict errors. labels Nov 8, 2016
@highfive highfive added S-awaiting-review There is new code that needs to be reviewed. and removed S-needs-code-changes Changes have not yet been made that were requested by a reviewer. labels Nov 8, 2016
@asajeffrey asajeffrey added the S-needs-squash Some (or all) of the commits in the PR should be combined. label Nov 8, 2016
@jdm jdm removed the S-awaiting-review There is new code that needs to be reviewed. label Nov 8, 2016
@jdm
Copy link
Copy Markdown
Member

jdm commented Nov 8, 2016

Looks good!

@asajeffrey asajeffrey force-pushed the constellation-manages-script-thread-lifetime branch from d27a481 to 08effa7 Compare November 8, 2016 21:42
@highfive highfive added the S-awaiting-review There is new code that needs to be reviewed. label Nov 8, 2016
@asajeffrey asajeffrey removed the S-needs-squash Some (or all) of the commits in the PR should be combined. label Nov 8, 2016
@asajeffrey
Copy link
Copy Markdown
Contributor Author

Squashed. @bors-servo r=jdm

@bors-servo
Copy link
Copy Markdown
Contributor

📌 Commit 08effa7 has been approved by jdm

@highfive highfive added S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. and removed S-awaiting-review There is new code that needs to be reviewed. labels Nov 8, 2016
@notriddle notriddle force-pushed the constellation-manages-script-thread-lifetime branch from 08effa7 to 0e7ffaf Compare November 9, 2016 01:29
@highfive highfive added S-awaiting-review There is new code that needs to be reviewed. and removed S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. labels Nov 9, 2016
@notriddle
Copy link
Copy Markdown
Contributor

@bors-servo r=jdm

@bors-servo
Copy link
Copy Markdown
Contributor

📌 Commit 0e7ffaf has been approved by jdm

@highfive highfive added S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. and removed S-awaiting-review There is new code that needs to be reviewed. labels Nov 9, 2016
@bors-servo
Copy link
Copy Markdown
Contributor

⌛ Testing commit 0e7ffaf with merge 13009fe...

bors-servo pushed a commit that referenced this pull request Nov 9, 2016
…-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 -->
@bors-servo
Copy link
Copy Markdown
Contributor

@bors-servo bors-servo merged commit 0e7ffaf into servo:master Nov 9, 2016
@highfive highfive removed the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Nov 9, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-constellation Involves the constellation A-content/script Related to the script thread I-refactor No impact; the issue is one of maintainability or tidiness. Proposed solution requires refactoring.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Share Script Threads by eTLD+1, not by parent origin

6 participants