diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2018-09-20 15:35:19 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-09-20 15:35:19 -0400 |
commit | 302e2cf5a4ba8b4e7bb3fce20f710a9d2ccd3d4e (patch) | |
tree | 349ffd023951a38dd9d3931912361bbc3f67f432 /components/script/dom/worklet.rs | |
parent | ac331c6663f50300a1b647ecf3fc3df9d46eac97 (diff) | |
parent | b3e85472eda2a017334a9faa3b33a3b4e0184e53 (diff) | |
download | servo-302e2cf5a4ba8b4e7bb3fce20f710a9d2ccd3d4e.tar.gz servo-302e2cf5a4ba8b4e7bb3fce20f710a9d2ccd3d4e.zip |
Auto merge of #21647 - AgustinCB:fix-space-leak-when-pipeline-is-closed, r=asajeffrey
Fix space leak when pipeline is closed
Add a new control message to drop remove worklets.
Implement `Drop` for `Worklet` and get the worklet thread pool. Use that
pool to send `ExitWorklet` to all the threads with the id of the
`Worklet` that it's dropping.
---
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix #17442
- [ ] There are tests for these changes OR
- [x] These changes do not require tests because I don't know how to add a test for this :(
If you consider this needs a test, could you point me out on how to write (and run!) one in this project? I gave this a couple tries, but I wasn't very successful.
<!-- 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/21647)
<!-- Reviewable:end -->
Diffstat (limited to 'components/script/dom/worklet.rs')
-rw-r--r-- | components/script/dom/worklet.rs | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/components/script/dom/worklet.rs b/components/script/dom/worklet.rs index 84a2b6f696b..5bcf81956e8 100644 --- a/components/script/dom/worklet.rs +++ b/components/script/dom/worklet.rs @@ -151,6 +151,13 @@ impl WorkletMethods for Worklet { } } +impl Drop for Worklet { + fn drop(&mut self) { + let script_thread = ScriptThread::worklet_thread_pool(); + script_thread.exit_worklet(self.worklet_id); + } +} + /// A guid for worklets. #[derive(Clone, Copy, Debug, Eq, Hash, JSTraceable, PartialEq)] pub struct WorkletId(Uuid); @@ -312,10 +319,14 @@ impl WorkletThreadPool { promise: TrustedPromise::new(promise.clone()), }); } - // If any of the threads are blocked waiting on data, wake them up. - let _ = self.cold_backup_sender.send(WorkletData::WakeUp); - let _ = self.hot_backup_sender.send(WorkletData::WakeUp); - let _ = self.primary_sender.send(WorkletData::WakeUp); + self.wake_threads(); + } + + pub(crate) fn exit_worklet(&self, worklet_id: WorkletId) { + for sender in &[&self.control_sender_0, &self.control_sender_1, &self.control_sender_2] { + let _ = sender.send(WorkletControl::ExitWorklet(worklet_id)); + } + self.wake_threads(); } /// For testing. @@ -325,6 +336,13 @@ impl WorkletThreadPool { let _ = self.primary_sender.send(msg); receiver.recv().expect("Test worklet has died?") } + + fn wake_threads(&self) { + // If any of the threads are blocked waiting on data, wake them up. + let _ = self.cold_backup_sender.send(WorkletData::WakeUp); + let _ = self.hot_backup_sender.send(WorkletData::WakeUp); + let _ = self.primary_sender.send(WorkletData::WakeUp); + } } /// The data messages sent to worklet threads @@ -338,6 +356,7 @@ enum WorkletData { /// The control message sent to worklet threads enum WorkletControl { + ExitWorklet(WorkletId), FetchAndInvokeAWorkletScript { pipeline_id: PipelineId, worklet_id: WorkletId, @@ -654,6 +673,9 @@ impl WorkletThread { /// Process a control message. fn process_control(&mut self, control: WorkletControl) { match control { + WorkletControl::ExitWorklet(worklet_id) => { + self.global_scopes.remove(&worklet_id); + }, WorkletControl::FetchAndInvokeAWorkletScript { pipeline_id, worklet_id, |