Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove redundant windowproxy transplanting #23967

Merged
merged 1 commit into from Aug 14, 2019

Conversation

@gterzian
Copy link
Member

gterzian commented Aug 14, 2019


  • ./mach build -d does not report any errors
  • ./mach test-tidy does not report any errors
  • These changes fix #___ (GitHub issue number if applicable)
  • There are tests for these changes OR
  • These changes do not require tests because ___

This change is Reviewable

@gterzian gterzian requested a review from asajeffrey Aug 14, 2019
@highfive
Copy link

highfive commented Aug 14, 2019

Heads up! This PR modifies the following files:

  • @asajeffrey: components/script/script_thread.rs, components/script/dom/window.rs
  • @KiChjang: components/script/script_thread.rs, components/script/dom/window.rs
@highfive
Copy link

highfive commented Aug 14, 2019

warning Warning warning

  • These commits modify script code, but no tests are modified. Please consider adding a test!
@gterzian gterzian force-pushed the gterzian:fix_double_transplant branch from 6a35726 to b8d5cd2 Aug 14, 2019
@gterzian
Copy link
Member Author

gterzian commented Aug 14, 2019

@asajeffrey The call to self.window_proxy().set_currently_active(self); inside window.resume seems redundant in two cases:

  1. When a new page is loaded, and we create a new windowproxy. See
    window.resume();
  2. When a new page is loaded, and we re-use a windowproxy, since we will already do the transplant at
    window_proxy.set_currently_active(&*window);

So I think the call is only necessary when we set the activity of a document to full-active, and there is no in progress load for that document(essentially I guess that's when re re-use a doc in the bfcache, and just set it to fully active).

In that case, the call is done inside document.set_activity, via a call to window.resume. I think it's probably clearer to do it as I've changed it here, and to remove the call inside window.resume, since most cases when we resume a window we do not need to transplant the windowproxy.

@gterzian gterzian force-pushed the gterzian:fix_double_transplant branch 3 times, most recently from 0951060 to 223fa8f Aug 14, 2019
@asajeffrey
Copy link
Member

asajeffrey commented Aug 14, 2019

This seems like a dangerous way to fix the issue, calling resume should make the document active. I'm concerned that with this change, we'd get weird race conditions about things like nested documents A with iframe B with iframe C, if C is resumed then B is resumed, since this should result in C being fully active but I'm not sure it will with this revision.

Is the case you're worried about one where we're transplanting a window proxy even though it's already in the right realm? If so, can we deal with this by adding a check to set_window to exit early if the proxy is already in the same realm as the window?

@gterzian
Copy link
Member Author

gterzian commented Aug 14, 2019

Is the case you're worried about one where we're transplanting a window proxy even though it's already in the right realm?

What I've noticed is that when we load a new url in an existing browsing-context, we hit the branch at

window_proxy.set_currently_active(&*window);

Then later we hit it again at

self.window_proxy().set_currently_active(self);

So we simply do the transplant twice, as far as I can tell.

In the other cases, we do the transplant only once as part of window.resume, and I still wonder whether it's not redundant, since in those other cases we actually create a windowproxy using the window, as in WindowProxy::new(&window, ..). Do we then still need to do a set_window after that?


The only other place in the code I could find that uses window.resume is at

self.window().resume();
,

which is called from

document.set_activity(activity);

That case seems necessary, since it deals with an existing window that becomes fully-active inside an existing browsing context.

So essentially that's the only place I added an explicit call to set_currently_active, as it seems necessary, as opposed to doing it in each call to resume, in which case it's often redundant.


can we deal with this by adding a check to set_window to exit early if the proxy is already in the same realm as the window?

Could we catch the redundancies inside

pub fn set_currently_active(&self, window: &Window) {

by checking the pipeline id of the window against self.currently_active? Yes we could because in those cases they're already the same, and then I assume the call to set_window is redundant?

It might still be better to only call set_currently_active when it's necessary, as opposed to making it idempotent?


I'm concerned that with this change, we'd get weird race conditions about things like nested documents A with iframe B with iframe C, if C is resumed then B is resumed, since this should result in C being fully active but I'm not sure it will with this revision.

There might be something I'm missing, and from reading the code it seems the above mentioned cases provide an exhaustive list of when set_window is called, so if the redundancies are correctly identified it seems we should not get weird side-effects.

Iframes are dealt as part of

let iframe = parent_info.and_then(|parent_id| {

and it seems that they get their own newly created windowproxy each time, hence the subsequent call to set_window that happens as part of window.resume would seem redundant.

@asajeffrey
Copy link
Member

asajeffrey commented Aug 14, 2019

I guess I'm worried that this change removes the transplanting from resume but not suspend, so they're not inverses. I see what you mean though, it is odd that local_window_proxy has a side-effect of setting the active document.

@gterzian
Copy link
Member Author

gterzian commented Aug 14, 2019

Ok, should I simply check the pipeline of the window against the currently active one, and return early, inside

pub fn set_currently_active(&self, window: &Window) {

That way we keep the current structure, and we just make "redundant" calls idempotent?

If self.currently_active is already the same as the pipeline id of the window passed as an argument, we never have to actually call set_window, or is there something else going on at the JS level?

@gterzian
Copy link
Member Author

gterzian commented Aug 14, 2019

By the way, I was also surprised to see that a call to suspend always sets a DissimilarOriginWindow as the current window on the proxy...

See

let window = DissimilarOriginWindow::new(&*globalscope, self);

@asajeffrey
Copy link
Member

asajeffrey commented Aug 14, 2019

Yeah, that is odd. I think it's because if the replacement window is similar-origin, then the constellation will send another message activating it. But it does mean there's a transient state where it appears to be a dissimilar-origin window, possibly resulting in spurious security errors.

@gterzian gterzian force-pushed the gterzian:fix_double_transplant branch from 223fa8f to 5c03337 Aug 14, 2019
@gterzian gterzian force-pushed the gterzian:fix_double_transplant branch from 5c03337 to d6e1820 Aug 14, 2019
@gterzian
Copy link
Member Author

gterzian commented Aug 14, 2019

Ok, the latest commit provides a fix that doesn't change the overall code stucture, ready for another review @asajeffrey

Copy link
Member

asajeffrey left a comment

A possible niggle about log levels, but otherwise LGTM.

let dest_pipeline_id = globalscope.pipeline_id();
if let Some(pipeline_id) = self.currently_active() {
if pipeline_id == dest_pipeline_id {
return warn!(

This comment has been minimized.

@asajeffrey

asajeffrey Aug 14, 2019

Member

Make this a debug! rather than a warn!?

This comment has been minimized.

@gterzian

gterzian Aug 14, 2019

Author Member

Ok, done.

@gterzian gterzian force-pushed the gterzian:fix_double_transplant branch from d6e1820 to 9acf3f6 Aug 14, 2019
@asajeffrey
Copy link
Member

asajeffrey commented Aug 14, 2019

@bors-servo
Copy link
Contributor

bors-servo commented Aug 14, 2019

📌 Commit 9acf3f6 has been approved by asajeffrey

@bors-servo
Copy link
Contributor

bors-servo commented Aug 14, 2019

Testing commit 9acf3f6 with merge 91469aa...

bors-servo added a commit that referenced this pull request Aug 14, 2019
Remove redundant windowproxy transplanting

<!-- Please describe your changes on the following line: -->

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: -->
- [ ] `./mach build -d` does not report any errors
- [ ] `./mach test-tidy` does not report any errors
- [ ] These changes fix #___ (GitHub issue number if applicable)

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because ___

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- 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/23967)
<!-- Reviewable:end -->
@bors-servo
Copy link
Contributor

bors-servo commented Aug 14, 2019

☀️ Test successful - linux-rel-css, linux-rel-wpt, status-taskcluster
Approved by: asajeffrey
Pushing 91469aa to master...

@bors-servo bors-servo merged commit 9acf3f6 into servo:master Aug 14, 2019
3 checks passed
3 checks passed
Taskcluster (pull_request) TaskGroup: success
Details
continuous-integration/appveyor/pr AppVeyor build succeeded
Details
homu Test successful
Details
@gterzian gterzian deleted the gterzian:fix_double_transplant branch Aug 15, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

4 participants
You can’t perform that action at this time.