diff options
author | Martin Robinson <mrobinson@igalia.com> | 2025-01-04 09:41:50 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-01-04 08:41:50 +0000 |
commit | b2eda71952f32c0e486c72ed881f472e59ad37c0 (patch) | |
tree | 281ac2c157d39859ebf9122d178d9c349f492a87 /components/script/dom/subtlecrypto.rs | |
parent | 75a22cfe2eb6c4822d5cda98e84cc88c1e4ce941 (diff) | |
download | servo-b2eda71952f32c0e486c72ed881f472e59ad37c0.tar.gz servo-b2eda71952f32c0e486c72ed881f472e59ad37c0.zip |
script: Move `TaskManager` to `GlobalScope` (#34827)
This is a simplification of the internal `TaskQueue` API that moves the
`TaskManager` to the `GlobalScope` itself. In addition, the handling of
cancellers is moved to the `TaskManager` as well. This means that no
arguments other than the `task` are necessary for queueing tasks, which
makes the API a lot easier to use and cleaner.
`TaskSource` now also keeps a copy of the canceller with it, so that
they always know the proper way to cancel any tasks queued on them.
There is one complication here. The event loop `sender` for dedicated
workers is constantly changing as it is set to `None` when not handling
messages. This is because this sender keeps a handle to the main
thread's `Worker` object, preventing garbage collection while any
messages are still in flight or being handled. This change allows
setting the `sender` on the `TaskManager` to `None` to allow proper
garbabge collection.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Diffstat (limited to 'components/script/dom/subtlecrypto.rs')
-rw-r--r-- | components/script/dom/subtlecrypto.rs | 283 |
1 files changed, 122 insertions, 161 deletions
diff --git a/components/script/dom/subtlecrypto.rs b/components/script/dom/subtlecrypto.rs index 344643ef3ce..077e367f394 100644 --- a/components/script/dom/subtlecrypto.rs +++ b/components/script/dom/subtlecrypto.rs @@ -40,7 +40,6 @@ use crate::dom::bindings::codegen::UnionTypes::{ }; use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::import::module::SafeJSContext; -use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::refcounted::{Trusted, TrustedPromise}; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; use crate::dom::bindings::root::DomRoot; @@ -49,12 +48,8 @@ use crate::dom::bindings::trace::RootedTraceableBox; use crate::dom::cryptokey::{CryptoKey, Handle}; use crate::dom::globalscope::GlobalScope; use crate::dom::promise::Promise; -use crate::dom::window::Window; -use crate::dom::workerglobalscope::WorkerGlobalScope; use crate::realms::InRealm; use crate::script_runtime::{CanGc, JSContext}; -use crate::task::TaskCanceller; -use crate::task_source::TaskSource; // String constants for algorithms/curves const ALG_AES_CBC: &str = "AES-CBC"; @@ -140,20 +135,6 @@ impl SubtleCrypto { CanGc::note(), ) } - - fn task_source_with_canceller(&self) -> (TaskSource, TaskCanceller) { - if let Some(window) = self.global().downcast::<Window>() { - window - .task_manager() - .dom_manipulation_task_source_with_canceller() - } else if let Some(worker_global) = self.global().downcast::<WorkerGlobalScope>() { - let task_source = worker_global.task_manager().dom_manipulation_task_source(); - let canceller = worker_global.task_canceller(); - (task_source, canceller) - } else { - unreachable!("Couldn't downcast to Window or WorkerGlobalScope!"); - } - } } impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { @@ -181,13 +162,13 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { ArrayBufferViewOrArrayBuffer::ArrayBuffer(buffer) => buffer.to_vec(), }; - let (task_source, canceller) = self.task_source_with_canceller(); + let task_source = self.global().task_manager().dom_manipulation_task_source(); let this = Trusted::new(self); let trusted_promise = TrustedPromise::new(promise.clone()); let trusted_key = Trusted::new(key); let key_alg = key.algorithm(); let valid_usage = key.usages().contains(&KeyUsage::Encrypt); - let _ = task_source.queue_with_canceller( + let _ = task_source.queue( task!(encrypt: move || { let subtle = this.root(); let promise = trusted_promise.root(); @@ -206,8 +187,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { return; } promise.resolve_native(&*array_buffer_ptr.handle()); - }), - &canceller, + }) ); promise @@ -237,13 +217,13 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { ArrayBufferViewOrArrayBuffer::ArrayBuffer(buffer) => buffer.to_vec(), }; - let (task_source, canceller) = self.task_source_with_canceller(); + let task_source = self.global().task_manager().dom_manipulation_task_source(); let this = Trusted::new(self); let trusted_promise = TrustedPromise::new(promise.clone()); let trusted_key = Trusted::new(key); let key_alg = key.algorithm(); let valid_usage = key.usages().contains(&KeyUsage::Decrypt); - let _ = task_source.queue_with_canceller( + let _ = task_source.queue( task!(decrypt: move || { let subtle = this.root(); let promise = trusted_promise.root(); @@ -262,8 +242,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { } promise.resolve_native(&*array_buffer_ptr.handle()); - }), - &canceller, + }) ); promise @@ -304,51 +283,48 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { // NOTE: We did that in preparation of Step 4. // Step 6. Return promise and perform the remaining steps in parallel. - let (task_source, canceller) = self.task_source_with_canceller(); + let task_source = self.global().task_manager().dom_manipulation_task_source(); let trusted_promise = TrustedPromise::new(promise.clone()); let trusted_key = Trusted::new(key); - let _ = task_source.queue_with_canceller( - task!(sign: move || { - // Step 7. If the following steps or referenced procedures say to throw an error, reject promise - // with the returned error and then terminate the algorithm. - let promise = trusted_promise.root(); - let key = trusted_key.root(); + let _ = task_source.queue(task!(sign: move || { + // Step 7. If the following steps or referenced procedures say to throw an error, reject promise + // with the returned error and then terminate the algorithm. + let promise = trusted_promise.root(); + let key = trusted_key.root(); + + // Step 8. If the name member of normalizedAlgorithm is not equal to the name attribute of the + // [[algorithm]] internal slot of key then throw an InvalidAccessError. + if normalized_algorithm.name() != key.algorithm() { + promise.reject_error(Error::InvalidAccess); + return; + } - // Step 8. If the name member of normalizedAlgorithm is not equal to the name attribute of the - // [[algorithm]] internal slot of key then throw an InvalidAccessError. - if normalized_algorithm.name() != key.algorithm() { - promise.reject_error(Error::InvalidAccess); - return; - } + // Step 9. If the [[usages]] internal slot of key does not contain an entry that is "sign", + // then throw an InvalidAccessError. + if !key.usages().contains(&KeyUsage::Sign) { + promise.reject_error(Error::InvalidAccess); + return; + } - // Step 9. If the [[usages]] internal slot of key does not contain an entry that is "sign", - // then throw an InvalidAccessError. - if !key.usages().contains(&KeyUsage::Sign) { - promise.reject_error(Error::InvalidAccess); + // Step 10. Let result be the result of performing the sign operation specified by normalizedAlgorithm + // using key and algorithm and with data as message. + let cx = GlobalScope::get_cx(); + let result = match normalized_algorithm.sign(cx, &key, &data) { + Ok(signature) => signature, + Err(e) => { + promise.reject_error(e); return; } + }; - // Step 10. Let result be the result of performing the sign operation specified by normalizedAlgorithm - // using key and algorithm and with data as message. - let cx = GlobalScope::get_cx(); - let result = match normalized_algorithm.sign(cx, &key, &data) { - Ok(signature) => signature, - Err(e) => { - promise.reject_error(e); - return; - } - }; - - rooted!(in(*cx) let mut array_buffer_ptr = ptr::null_mut::<JSObject>()); - create_buffer_source::<ArrayBufferU8>(cx, &result, array_buffer_ptr.handle_mut()) - .expect("failed to create buffer source for exported key."); + rooted!(in(*cx) let mut array_buffer_ptr = ptr::null_mut::<JSObject>()); + create_buffer_source::<ArrayBufferU8>(cx, &result, array_buffer_ptr.handle_mut()) + .expect("failed to create buffer source for exported key."); - // Step 9. Resolve promise with result. - promise.resolve_native(&*array_buffer_ptr); - }), - &canceller, - ); + // Step 9. Resolve promise with result. + promise.resolve_native(&*array_buffer_ptr); + })); promise } @@ -397,47 +373,44 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { // NOTE: We did that in preparation of Step 6. // Step 7. Return promise and perform the remaining steps in parallel. - let (task_source, canceller) = self.task_source_with_canceller(); + let task_source = self.global().task_manager().dom_manipulation_task_source(); let trusted_promise = TrustedPromise::new(promise.clone()); let trusted_key = Trusted::new(key); - let _ = task_source.queue_with_canceller( - task!(sign: move || { - // Step 8. If the following steps or referenced procedures say to throw an error, reject promise - // with the returned error and then terminate the algorithm. - let promise = trusted_promise.root(); - let key = trusted_key.root(); + let _ = task_source.queue(task!(sign: move || { + // Step 8. If the following steps or referenced procedures say to throw an error, reject promise + // with the returned error and then terminate the algorithm. + let promise = trusted_promise.root(); + let key = trusted_key.root(); + + // Step 9. If the name member of normalizedAlgorithm is not equal to the name attribute of the + // [[algorithm]] internal slot of key then throw an InvalidAccessError. + if normalized_algorithm.name() != key.algorithm() { + promise.reject_error(Error::InvalidAccess); + return; + } - // Step 9. If the name member of normalizedAlgorithm is not equal to the name attribute of the - // [[algorithm]] internal slot of key then throw an InvalidAccessError. - if normalized_algorithm.name() != key.algorithm() { - promise.reject_error(Error::InvalidAccess); - return; - } + // Step 10. If the [[usages]] internal slot of key does not contain an entry that is "verify", + // then throw an InvalidAccessError. + if !key.usages().contains(&KeyUsage::Verify) { + promise.reject_error(Error::InvalidAccess); + return; + } - // Step 10. If the [[usages]] internal slot of key does not contain an entry that is "verify", - // then throw an InvalidAccessError. - if !key.usages().contains(&KeyUsage::Verify) { - promise.reject_error(Error::InvalidAccess); + // Step 1. Let result be the result of performing the verify operation specified by normalizedAlgorithm + // using key, algorithm and signature and with data as message. + let cx = GlobalScope::get_cx(); + let result = match normalized_algorithm.verify(cx, &key, &data, &signature) { + Ok(result) => result, + Err(e) => { + promise.reject_error(e); return; } + }; - // Step 1. Let result be the result of performing the verify operation specified by normalizedAlgorithm - // using key, algorithm and signature and with data as message. - let cx = GlobalScope::get_cx(); - let result = match normalized_algorithm.verify(cx, &key, &data, &signature) { - Ok(result) => result, - Err(e) => { - promise.reject_error(e); - return; - } - }; - - // Step 9. Resolve promise with result. - promise.resolve_native(&result); - }), - &canceller, - ); + // Step 9. Resolve promise with result. + promise.resolve_native(&result); + })); promise } @@ -476,10 +449,10 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { // NOTE: We did that in preparation of Step 4. // Step 6. Return promise and perform the remaining steps in parallel. - let (task_source, canceller) = self.task_source_with_canceller(); + let task_source = self.global().task_manager().dom_manipulation_task_source(); let trusted_promise = TrustedPromise::new(promise.clone()); - let _ = task_source.queue_with_canceller( + let _ = task_source.queue( task!(generate_key: move || { // Step 7. If the following steps or referenced procedures say to throw an error, reject promise // with the returned error and then terminate the algorithm. @@ -503,8 +476,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { // Step 9. Resolve promise with result. promise.resolve_native(&*array_buffer_ptr); - }), - &canceller, + }) ); promise @@ -529,22 +501,19 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { }, }; - let (task_source, canceller) = self.task_source_with_canceller(); + let task_source = self.global().task_manager().dom_manipulation_task_source(); let this = Trusted::new(self); let trusted_promise = TrustedPromise::new(promise.clone()); - let _ = task_source.queue_with_canceller( - task!(generate_key: move || { - let subtle = this.root(); - let promise = trusted_promise.root(); - let key = normalized_algorithm.generate_key(&subtle, key_usages, extractable); - - match key { - Ok(key) => promise.resolve_native(&key), - Err(e) => promise.reject_error(e), - } - }), - &canceller, - ); + let _ = task_source.queue(task!(generate_key: move || { + let subtle = this.root(); + let promise = trusted_promise.root(); + let key = normalized_algorithm.generate_key(&subtle, key_usages, extractable); + + match key { + Ok(key) => promise.resolve_native(&key), + Err(e) => promise.reject_error(e), + } + })); promise } @@ -604,11 +573,11 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { // NOTE: We created the promise earlier, after Step 1. // Step 9. Return promise and perform the remaining steps in parallel. - let (task_source, canceller) = self.task_source_with_canceller(); + let task_source = self.global().task_manager().dom_manipulation_task_source(); let trusted_promise = TrustedPromise::new(promise.clone()); let trusted_base_key = Trusted::new(base_key); let this = Trusted::new(self); - let _ = task_source.queue_with_canceller( + let _ = task_source.queue( task!(derive_key: move || { // Step 10. If the following steps or referenced procedures say to throw an error, reject promise // with the returned error and then terminate the algorithm. @@ -674,7 +643,6 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { // Step 17. Resolve promise with result. promise.resolve_native(&*result); }), - &canceller, ); promise @@ -709,47 +677,44 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { // NOTE: We did that in preparation of Step 3. // Step 5. Return promise and perform the remaining steps in parallel. - let (task_source, canceller) = self.task_source_with_canceller(); + let task_source = self.global().task_manager().dom_manipulation_task_source(); let trusted_promise = TrustedPromise::new(promise.clone()); let trusted_base_key = Trusted::new(base_key); - let _ = task_source.queue_with_canceller( - task!(import_key: move || { - // Step 6. If the following steps or referenced procedures say to throw an error, - // reject promise with the returned error and then terminate the algorithm. + let _ = task_source.queue(task!(import_key: move || { + // Step 6. If the following steps or referenced procedures say to throw an error, + // reject promise with the returned error and then terminate the algorithm. - // TODO Step 7. If the name member of normalizedAlgorithm is not equal to the name attribute - // of the [[algorithm]] internal slot of baseKey then throw an InvalidAccessError. - let promise = trusted_promise.root(); - let base_key = trusted_base_key.root(); + // TODO Step 7. If the name member of normalizedAlgorithm is not equal to the name attribute + // of the [[algorithm]] internal slot of baseKey then throw an InvalidAccessError. + let promise = trusted_promise.root(); + let base_key = trusted_base_key.root(); - // Step 8. If the [[usages]] internal slot of baseKey does not contain an entry that - // is "deriveBits", then throw an InvalidAccessError. - if !base_key.usages().contains(&KeyUsage::DeriveBits) { - promise.reject_error(Error::InvalidAccess); + // Step 8. If the [[usages]] internal slot of baseKey does not contain an entry that + // is "deriveBits", then throw an InvalidAccessError. + if !base_key.usages().contains(&KeyUsage::DeriveBits) { + promise.reject_error(Error::InvalidAccess); + return; + } + + // Step 9. Let result be the result of creating an ArrayBuffer containing the result of performing the + // derive bits operation specified by normalizedAlgorithm using baseKey, algorithm and length. + let cx = GlobalScope::get_cx(); + rooted!(in(*cx) let mut array_buffer_ptr = ptr::null_mut::<JSObject>()); + let result = match normalized_algorithm.derive_bits(&base_key, length) { + Ok(derived_bits) => derived_bits, + Err(e) => { + promise.reject_error(e); return; } + }; - // Step 9. Let result be the result of creating an ArrayBuffer containing the result of performing the - // derive bits operation specified by normalizedAlgorithm using baseKey, algorithm and length. - let cx = GlobalScope::get_cx(); - rooted!(in(*cx) let mut array_buffer_ptr = ptr::null_mut::<JSObject>()); - let result = match normalized_algorithm.derive_bits(&base_key, length) { - Ok(derived_bits) => derived_bits, - Err(e) => { - promise.reject_error(e); - return; - } - }; - - create_buffer_source::<ArrayBufferU8>(cx, &result, array_buffer_ptr.handle_mut()) - .expect("failed to create buffer source for derived bits."); + create_buffer_source::<ArrayBufferU8>(cx, &result, array_buffer_ptr.handle_mut()) + .expect("failed to create buffer source for derived bits."); - // Step 10. Resolve promise with result. - promise.resolve_native(&*array_buffer_ptr); - }), - &canceller, - ); + // Step 10. Resolve promise with result. + promise.resolve_native(&*array_buffer_ptr); + })); promise } @@ -801,10 +766,10 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { }, }; - let (task_source, canceller) = self.task_source_with_canceller(); + let task_source = self.global().task_manager().dom_manipulation_task_source(); let this = Trusted::new(self); let trusted_promise = TrustedPromise::new(promise.clone()); - let _ = task_source.queue_with_canceller( + let _ = task_source.queue( task!(import_key: move || { let subtle = this.root(); let promise = trusted_promise.root(); @@ -814,7 +779,6 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { Err(e) => promise.reject_error(e), }; }), - &canceller, ); promise @@ -830,11 +794,11 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { ) -> Rc<Promise> { let promise = Promise::new_in_current_realm(comp, can_gc); - let (task_source, canceller) = self.task_source_with_canceller(); + let task_source = self.global().task_manager().dom_manipulation_task_source(); let this = Trusted::new(self); let trusted_key = Trusted::new(key); let trusted_promise = TrustedPromise::new(promise.clone()); - let _ = task_source.queue_with_canceller( + let _ = task_source.queue( task!(export_key: move || { let subtle = this.root(); let promise = trusted_promise.root(); @@ -872,7 +836,6 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { Err(e) => promise.reject_error(e), } }), - &canceller, ); promise @@ -898,12 +861,12 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { }, }; - let (task_source, canceller) = self.task_source_with_canceller(); + let task_source = self.global().task_manager().dom_manipulation_task_source(); let this = Trusted::new(self); let trusted_key = Trusted::new(key); let trusted_wrapping_key = Trusted::new(wrapping_key); let trusted_promise = TrustedPromise::new(promise.clone()); - let _ = task_source.queue_with_canceller( + let _ = task_source.queue( task!(wrap_key: move || { let subtle = this.root(); let promise = trusted_promise.root(); @@ -996,7 +959,6 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { Err(e) => promise.reject_error(e), } }), - &canceller ); promise @@ -1037,11 +999,11 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { }, }; - let (task_source, canceller) = self.task_source_with_canceller(); + let task_source = self.global().task_manager().dom_manipulation_task_source(); let this = Trusted::new(self); let trusted_key = Trusted::new(unwrapping_key); let trusted_promise = TrustedPromise::new(promise.clone()); - let _ = task_source.queue_with_canceller( + let _ = task_source.queue( task!(unwrap_key: move || { let subtle = this.root(); let promise = trusted_promise.root(); @@ -1103,7 +1065,6 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { Err(e) => promise.reject_error(e), } }), - &canceller ); promise |