diff options
Diffstat (limited to 'components/shared/embedder/lib.rs')
-rw-r--r-- | components/shared/embedder/lib.rs | 75 |
1 files changed, 74 insertions, 1 deletions
diff --git a/components/shared/embedder/lib.rs b/components/shared/embedder/lib.rs index 5f1171859dc..c87fa9019ef 100644 --- a/components/shared/embedder/lib.rs +++ b/components/shared/embedder/lib.rs @@ -14,7 +14,7 @@ pub mod user_content_manager; mod webdriver; use std::ffi::c_void; -use std::fmt::{Debug, Error, Formatter}; +use std::fmt::{Debug, Display, Error, Formatter}; use std::path::PathBuf; use std::sync::Arc; @@ -784,3 +784,76 @@ pub enum AnimationState { /// No animations are active but callbacks are queued NoAnimationCallbacksPresent, } + +/// A sequence number generated by a script thread for its pipelines. The +/// constellation attaches the target pipeline's last seen `FocusSequenceNumber` +/// to every focus-related message it sends. +/// +/// This is used to resolve the inconsistency that occurs due to bidirectional +/// focus state synchronization and provide eventual consistency. Example: +/// +/// ```text +/// script constellation +/// ----------------------------------------------------------------------- +/// send ActivateDocument ----------> receive ActivateDocument +/// ,---- send FocusDocument +/// | +/// focus an iframe | +/// send Focus -----------------|---> receive Focus +/// | focus the iframe's content document +/// receive FocusDocument <-----' send FocusDocument to the content pipeline --> ... +/// unfocus the iframe +/// focus the document +/// +/// Final state: Final state: +/// the iframe is not focused the iframe is focused +/// ``` +/// +/// When the above sequence completes, from the script thread's point of view, +/// the iframe is unfocused, but from the constellation's point of view, the +/// iframe is still focused. +/// +/// This inconsistency can be resolved by associating a sequence number to each +/// message. Whenever a script thread initiates a focus operation, it generates +/// and sends a brand new sequence number. The constellation attaches the +/// last-received sequence number to each message it sends. This way, the script +/// thread can discard out-dated incoming focus messages, and eventually, all +/// actors converge to the consistent state which is determined based on the +/// last focus message received by the constellation. +/// +/// ```text +/// script constellation +/// ----------------------------------------------------------------------- +/// send ActivateDocument ----------> receive ActivateDocument +/// ,---- send FocusDocument (0) +/// | +/// seq_number += 1 | +/// focus an iframe | +/// send Focus (1) -------------|---> receive Focus (1) +/// | focus the iframe's content document +/// receive FocusDocument (0) <-' send FocusDocument to the content pipeline --> ... +/// ignore it because 0 < 1 +/// +/// Final state: Final state: +/// the iframe is focused the iframe is focused +/// ``` +#[derive( + Clone, + Copy, + Debug, + Default, + Deserialize, + Eq, + Hash, + MallocSizeOf, + PartialEq, + Serialize, + PartialOrd, +)] +pub struct FocusSequenceNumber(pub u64); + +impl Display for FocusSequenceNumber { + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> { + Display::fmt(&self.0, f) + } +} |