aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/subtlecrypto.rs
diff options
context:
space:
mode:
authorMartin Robinson <mrobinson@igalia.com>2025-01-04 09:41:50 +0100
committerGitHub <noreply@github.com>2025-01-04 08:41:50 +0000
commitb2eda71952f32c0e486c72ed881f472e59ad37c0 (patch)
tree281ac2c157d39859ebf9122d178d9c349f492a87 /components/script/dom/subtlecrypto.rs
parent75a22cfe2eb6c4822d5cda98e84cc88c1e4ce941 (diff)
downloadservo-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.rs283
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