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

Make image cache per-document rather than global #16048

Merged
merged 4 commits into from Mar 27, 2017

Conversation

@ferjm
Copy link
Member

ferjm commented Mar 20, 2017

  • ./mach build -d does not report any errors
  • ./mach test-tidy does not report any errors
  • These changes fix #15701.
  • These changes do not require new tests because there should already be WPTs for image loads.

This change is Reviewable

@highfive
Copy link

highfive commented Mar 20, 2017

Heads up! This PR modifies the following files:

  • @asajeffrey: components/constellation/pipeline.rs, components/constellation/constellation.rs
  • @KiChjang: components/net/lib.rs, components/script/layout_image.rs, components/script/dom/htmlcanvaselement.rs, components/script/dom/window.rs, components/script_traits/lib.rs, components/script_traits/lib.rs, components/net_traits/lib.rs, components/net_traits/lib.rs, components/net_traits/image_cache_thread.rs, components/net_traits/image_cache_thread.rs, components/net_traits/image_cache.rs, components/net_traits/image_cache.rs, components/script/dom/htmlimageelement.rs, components/script_layout_interface/lib.rs, components/script/script_thread.rs, components/script_layout_interface/message.rs, components/net/image_cache_thread.rs, components/script/dom/webglrenderingcontext.rs, components/script/dom/bindings/trace.rs, components/script/dom/canvasrenderingcontext2d.rs, components/net_traits/Cargo.toml, components/net_traits/Cargo.toml
  • @fitzgen: components/script/layout_image.rs, components/script/dom/htmlcanvaselement.rs, components/script/dom/window.rs, components/script_traits/lib.rs, components/script_traits/lib.rs, components/script/dom/htmlimageelement.rs, components/script_layout_interface/lib.rs, components/script/script_thread.rs, components/script_layout_interface/message.rs, components/script/dom/webglrenderingcontext.rs, components/script/dom/bindings/trace.rs, components/script/dom/canvasrenderingcontext2d.rs
  • @emilio: components/layout/display_list_builder.rs, components/layout/context.rs, components/layout/fragment.rs, components/script/dom/webglrenderingcontext.rs
@highfive
Copy link

highfive commented Mar 20, 2017

warning Warning warning

  • These commits modify net, layout, and script code, but no tests are modified. Please consider adding a test!
@ferjm
Copy link
Member Author

ferjm commented Mar 20, 2017

r? @jdm

@highfive highfive assigned jdm and unassigned Manishearth Mar 20, 2017
@jdm
Copy link
Member

jdm commented Mar 20, 2017

One thing I see when skimming this PR - by moving image_cache_thread from net to net_traits, we make changing its implementation take longer to compile. We should consider moving the implementation back to net and providing a trait in net_traits for consumers instead.

@ferjm ferjm force-pushed the ferjm:issue-15701-image-cache branch 2 times, most recently from 2c6ff8f to f9968f7 Mar 20, 2017
@ferjm
Copy link
Member Author

ferjm commented Mar 21, 2017

@bors-servo
Copy link
Contributor

bors-servo commented Mar 21, 2017

@ferjm: 🔑 Insufficient privileges: and not in try users

@ferjm
Copy link
Member Author

ferjm commented Mar 21, 2017

@jdm it seems that I still don't have privileges to trigger try runs. I guess servo/saltfs@09aa211 has not been pushed to production yet. Could you trigger a try run for me, please? I'd like to see if this patch breaks any tests. Thank you!

@jdm
Copy link
Member

jdm commented Mar 21, 2017

@bors-servo
Copy link
Contributor

bors-servo commented Mar 21, 2017

Trying commit f9968f7 with merge 54a3309...

bors-servo added a commit that referenced this pull request Mar 21, 2017
Make image cache per-document rather than global

- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix #15701.
- [X] These changes do not require new tests because there should already be WPTs for image loads.

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

bors-servo commented Mar 21, 2017

Copy link
Member

jdm left a comment

Good start! There are some tricky details that we still need to get right, however.


// Webrender API instance.
webrender_api: Mutex<webrender_traits::RenderApi>,

This comment has been minimized.

@jdm

jdm Mar 21, 2017

Member

I'm tempted to recommend that we should avoid storing separate mutexes inside ImageCache, and make consumers wrap it in a single Mutex instead.

This comment has been minimized.

@ferjm

ferjm Mar 22, 2017

Author Member

May I ask why? :) I would prefer to hide the Mutex complexity to consumers.

This comment has been minimized.

@jdm

jdm Mar 22, 2017

Member

Multiple mutexes introduce opportunities for deadlocks. I would prefer to rely on Rust's borrow checker and write methods that accept &mut self arguments, rather than wrapping each member in a separate Mutex.

This comment has been minimized.

@ferjm

ferjm Mar 22, 2017

Author Member

Ok, thanks for the explanation.

I am a bit blocked trying to address this comment. I think I understand the issue, but I am not sure how to solve it.

So the ImageCacheImpl struct has a webrender_traits::RenderApi member and webrender_traits::RenderApi contains a Cell<webrender_traits::ResourceId>. The thing is that Cell implements Send but not Sync and I was solving this by wrapping the RenderApi member in its own Mutex. But now, removing this Mutex and wrapping the entire ImageCacheImpl in a Mutex makes the compiler unhappy:

rror[E0277]: the trait bound `std::cell::Cell<webrender_traits::ResourceId>: std::marker::Sync` is not satisfied in `image_cache::ImageCacheImpl`
   --> /Volumes/mozilladev/servo/components/net/image_cache.rs:406:6
    |
406 | impl ImageCache for ImageCacheImpl {
    |      ^^^^^^^^^^ within `image_cache::ImageCacheImpl`, the trait `std::marker::Sync` is not implemented for `std::cell::Cell<webrender_traits::ResourceId>`
    |
    = note: `std::cell::Cell<webrender_traits::ResourceId>` cannot be shared between threads safely
    = note: required because it appears within the type `webrender_traits::RenderApi`
    = note: required because it appears within the type `image_cache::ImageCacheImpl`
    = note: required by `net_traits::image_cache::ImageCache`

error[E0277]: the trait bound `std::cell::Cell<()>: std::marker::Sync` is not satisfied in `image_cache::ImageCacheImpl`
   --> /Volumes/mozilladev/servo/components/net/image_cache.rs:406:6
    |
406 | impl ImageCache for ImageCacheImpl {
    |      ^^^^^^^^^^ within `image_cache::ImageCacheImpl`, the trait `std::marker::Sync` is not implemented for `std::cell::Cell<()>`
    |
    = note: `std::cell::Cell<()>` cannot be shared between threads safely
    = note: required because it appears within the type `std::marker::PhantomData<std::cell::Cell<()>>`
    = note: required because it appears within the type `ipc_channel::platform::OsIpcSender`
    = note: required because it appears within the type `ipc_channel::ipc::IpcSender<webrender_traits::ApiMsg>`
    = note: required because it appears within the type `webrender_traits::RenderApi`
    = note: required because it appears within the type `image_cache::ImageCacheImpl`
    = note: required by `net_traits::image_cache::ImageCache`

@jdm should I keep the Mutex for the webrender_traits::RenderApi member? Or is there a better way to solve this?

This comment has been minimized.

@ferjm

ferjm Mar 22, 2017

Author Member

Nevermind. I think I fixed it.


// Public API

pub fn new(webrender_api: webrender_traits::RenderApi) -> Arc<ImageCache> {

This comment has been minimized.

@jdm

jdm Mar 21, 2017

Member

Let's extract the public API into a trait that lives in net_traits/image_cache.rs, and move the implementation back into net_traits/image_cache.rs.

This comment has been minimized.

@ferjm

ferjm Mar 22, 2017

Author Member

Yes, this was done in the second commit.

DecoderMsg {
key: key,
image: image
if let Some(msg) = rx.recv().ok() {

This comment has been minimized.

@jdm

jdm Mar 21, 2017

Member

Synchronously waiting on the result here makes spawning a thread redundant. We should call handle_decoder from inside the thread instead, but that suddenly makes this code more complicated to write. Maybe notify_pending_response needs to accept an additional argument which is an Arc for self? The other option is to given the image cache an interface it can use to enqueue an async operation to call handle_decoder on the original thread; this would mean that there is no risk of an image being decoded halfway through a layout operation, which sounds like a good idea.

This comment has been minimized.

@ferjm

ferjm Mar 27, 2017

Author Member

Fixed in the 3rd commit.

@@ -48,4 +48,4 @@ pub trait LayoutThreadFactory {
content_process_shutdown_chan: Option<IpcSender<()>>,
webrender_api_sender: webrender_traits::RenderApiSender,
layout_threads: usize);
}
}

This comment has been minimized.

@jdm

jdm Mar 21, 2017

Member

Unintentional?

This comment has been minimized.

@ferjm

ferjm Mar 22, 2017

Author Member

Yes :)

@ferjm ferjm force-pushed the ferjm:issue-15701-image-cache branch from f9968f7 to d9bb5d0 Mar 22, 2017
@ferjm
Copy link
Member Author

ferjm commented Mar 22, 2017

@jdm my last commit is not exactly what you were asking for, but I think it's a good middle ground solution where we have a single Mutex for the ImageCache data as you suggested but we don't require consumers to explicitly wrap with a Mutex and request the locks. I also removed the synchronous wait after spawning the image decoding thread. Thanks for your feedback!

@ferjm ferjm requested a review from jdm Mar 27, 2017
@@ -405,14 +401,39 @@ impl ImageCacheImpl {
}
}

struct ImageDecoderRunnable {

This comment has been minimized.

@jdm

jdm Mar 27, 2017

Member

I don't see a reason for this separate structure rather than having the code inline in the caller of run.

}
}

pub struct ImageCacheImpl {

This comment has been minimized.

@jdm

jdm Mar 27, 2017

Member

All the code using this now puts it in an extra Arc, right? Can we fix that by making this structure Clone and storing ImageCacheImpl (perhaps renaming it to ImageCacheHandle).

This comment has been minimized.

@ferjm

ferjm Mar 27, 2017

Author Member

@jdm if I am not wrong, this means that I need to use net::image_cache::ImageCacheHandle instead of net_traits::image_cache::ImageCache in all consumers, is this ok?

This comment has been minimized.

@jdm

jdm Mar 27, 2017

Member

Bleah, you're right. Let's leave it the way it is.

@ferjm ferjm force-pushed the ferjm:issue-15701-image-cache branch from d9bb5d0 to fa433a7 Mar 27, 2017
@ferjm ferjm requested a review from jdm Mar 27, 2017
@jdm
Copy link
Member

jdm commented Mar 27, 2017

@bors-servo
Copy link
Contributor

bors-servo commented Mar 27, 2017

📌 Commit fa433a7 has been approved by jdm

@bors-servo
Copy link
Contributor

bors-servo commented Mar 27, 2017

Testing commit fa433a7 with merge c85a02b...

bors-servo added a commit that referenced this pull request Mar 27, 2017
Make image cache per-document rather than global

- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix #15701.
- [X] These changes do not require new tests because there should already be WPTs for image loads.

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

bors-servo commented Mar 27, 2017

💔 Test failed - mac-rel-wpt1

@jdm
Copy link
Member

jdm commented Mar 27, 2017

@bors-servo
Copy link
Contributor

bors-servo commented Mar 27, 2017

Previous build results for android, arm32, arm64, linux-dev, linux-rel-css, linux-rel-wpt, mac-dev-unit, mac-rel-css, mac-rel-wpt2, windows-msvc-dev are reusable. Rebuilding only mac-rel-wpt1...

@bors-servo
Copy link
Contributor

bors-servo commented Mar 27, 2017

💔 Test failed - mac-rel-wpt1

@jdm
Copy link
Member

jdm commented Mar 27, 2017

@bors-servo
Copy link
Contributor

bors-servo commented Mar 27, 2017

Previous build results for android, arm32, arm64, linux-dev, linux-rel-css, linux-rel-wpt, mac-dev-unit, mac-rel-css, mac-rel-wpt2, windows-msvc-dev are reusable. Rebuilding only mac-rel-wpt1...

@bors-servo
Copy link
Contributor

bors-servo commented Mar 27, 2017

☀️ Test successful - android, arm32, arm64, linux-dev, linux-rel-css, linux-rel-wpt, mac-dev-unit, mac-rel-css, mac-rel-wpt1, mac-rel-wpt2, windows-msvc-dev
Approved by: jdm
Pushing c85a02b to master...

@bors-servo bors-servo merged commit fa433a7 into servo:master Mar 27, 2017
3 checks passed
3 checks passed
continuous-integration/appveyor/pr AppVeyor build succeeded
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
homu Test successful
Details
@ferjm ferjm deleted the ferjm:issue-15701-image-cache branch Mar 28, 2017
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.

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