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

Implement MessagePort and MessageChannel #16622

Closed
wants to merge 15 commits into from
Closed
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Accept origin as a parameter in dispatch_jsval

  • Loading branch information
KiChjang committed Jun 11, 2019
commit 4da8a003c90fb05214267222ea2a64ee6d6bc2cb
@@ -12,7 +12,10 @@ pub enum WorkerScriptMsg {
/// Common variants associated with the script messages
Common(CommonScriptMsg),
/// Message sent through Worker.postMessage
DOMMessage(StructuredCloneData),
DOMMessage {
origin: String,
data: StructuredCloneData,
}
}

pub struct SimpleWorkerErrorHandler<T: DomObject> {
@@ -75,7 +75,7 @@ impl ScriptPort for Receiver<DedicatedWorkerScriptMsg> {
};
match common_msg {
WorkerScriptMsg::Common(script_msg) => Ok(script_msg),
WorkerScriptMsg::DOMMessage(_) => panic!("unexpected worker event message!"),
WorkerScriptMsg::DOMMessage { .. } => panic!("unexpected worker event message!"),
}
}
}
@@ -459,13 +459,20 @@ impl DedicatedWorkerGlobalScope {

fn handle_script_event(&self, msg: WorkerScriptMsg) {
match msg {
WorkerScriptMsg::DOMMessage(data) => {
WorkerScriptMsg::DOMMessage { origin, data } => {
let scope = self.upcast::<WorkerGlobalScope>();
let target = self.upcast();
let _ac = JSAutoRealm::new(scope.get_cx(), scope.reflector().get_jsobject().get());
rooted!(in(scope.get_cx()) let mut message = UndefinedValue());
assert!(data.read(scope.upcast(), message.handle_mut()));
MessageEvent::dispatch_jsval(target, scope.upcast(), message.handle(), None, None, vec![]);
MessageEvent::dispatch_jsval(
target,
scope.upcast(),
message.handle(),
Some(&origin),
None,
vec![],
);
},
WorkerScriptMsg::Common(msg) => {
self.upcast::<WorkerGlobalScope>().process_event(msg);
@@ -563,9 +570,10 @@ impl DedicatedWorkerGlobalScopeMethods for DedicatedWorkerGlobalScope {
rooted!(in(cx) let transfer = UndefinedValue());
let data = StructuredCloneData::write(cx, message, transfer.handle())?;
let worker = self.worker.borrow().as_ref().unwrap().clone();
let pipeline_id = self.upcast::<GlobalScope>().pipeline_id();
let pipeline_id = self.global().pipeline_id();
let origin = self.global().origin().immutable().ascii_serialization();
let task = Box::new(task!(post_worker_message: move || {
Worker::handle_message(worker, data);
Worker::handle_message(worker, origin, data);
}));
// TODO: Change this task source to a new `unshipped-port-message-queue` task source
self.parent_sender
@@ -35,12 +35,12 @@ thread_local! {
}

struct PortMessageTask {
origin: String,
data: Vec<u8>,
}

pub struct MessagePortInternal {
dom_port: RefCell<Option<Trusted<MessagePort>>>,
origin: RefCell<String>,
port_message_queue: RefCell<PortMessageQueue>,
enabled: Cell<bool>,
has_been_shipped: Cell<bool>,
@@ -49,10 +49,9 @@ pub struct MessagePortInternal {
}

impl MessagePortInternal {
fn new(port_message_queue: PortMessageQueue, origin: String) -> MessagePortInternal {
fn new(port_message_queue: PortMessageQueue) -> MessagePortInternal {
MessagePortInternal {
dom_port: RefCell::new(None),
origin: RefCell::new(origin),
port_message_queue: RefCell::new(port_message_queue),
enabled: Cell::new(false),
has_been_shipped: Cell::new(false),
@@ -65,7 +64,7 @@ impl MessagePortInternal {
// Step 7 substeps
#[allow(unrooted_must_root)]
fn process_pending_port_messages(&self) {
if let Some(task) = self.pending_port_messages.borrow_mut().pop_front() {
if let Some(PortMessageTask { origin, data }) = self.pending_port_messages.borrow_mut().pop_front() {
// Substep 1
let final_target_port = self.dom_port.borrow().as_ref().unwrap().root();

@@ -74,7 +73,7 @@ impl MessagePortInternal {

// Substep 3-4
rooted!(in(target_global.get_cx()) let mut message_clone = UndefinedValue());
let deserialize_result = StructuredCloneData::Vector(task.data).read(
let deserialize_result = StructuredCloneData::Vector(data).read(
&target_global,
message_clone.handle_mut(),
);
@@ -92,7 +91,7 @@ impl MessagePortInternal {
final_target_port.upcast(),
&target_global,
message_clone.handle(),
Some(&self.origin.borrow()),
Some(&origin),
None,
new_ports,
);
@@ -129,27 +128,19 @@ impl HasParent for MessagePort {
}

impl MessagePort {
fn new_inherited(global: &GlobalScope, origin: String) -> MessagePort {
fn new_inherited(global: &GlobalScope) -> MessagePort {
MessagePort {
eventtarget: EventTarget::new_inherited(),
detached: Cell::new(false),
message_port_internal: Arc::new(
ReentrantMutex::new(
MessagePortInternal::new(global.port_message_queue().clone(), origin)
MessagePortInternal::new(global.port_message_queue().clone())
)
),
}
}

fn new_transferred(
message_port_internal: Arc<ReentrantMutex<MessagePortInternal>>,
origin: String,
) -> MessagePort {
{
let internal = message_port_internal.lock().unwrap();
*internal.origin.borrow_mut() = origin;
}

fn new_transferred(message_port_internal: Arc<ReentrantMutex<MessagePortInternal>>) -> MessagePort {
MessagePort {
eventtarget: EventTarget::new_inherited(),
detached: Cell::new(false),
@@ -159,8 +150,7 @@ impl MessagePort {

/// <https://html.spec.whatwg.org/multipage/#create-a-new-messageport-object>
pub fn new(owner: &GlobalScope) -> DomRoot<MessagePort> {
let origin = owner.origin().immutable().ascii_serialization();
let message_port = reflect_dom_object(Box::new(MessagePort::new_inherited(owner, origin)), owner, Wrap);
let message_port = reflect_dom_object(Box::new(MessagePort::new_inherited(owner)), owner, Wrap);
{
let internal = message_port.message_port_internal.lock().unwrap();
*internal.dom_port.borrow_mut() = Some(Trusted::new(&*message_port));
@@ -229,12 +219,11 @@ impl Transferable for MessagePort {
_extra_data: u64,
return_object: MutableHandleObject
) -> bool {
let owner = unsafe { GlobalScope::from_context(cx) };

let internal = unsafe { Arc::from_raw(content as *const ReentrantMutex<MessagePortInternal>) };
let value = MessagePort::new_transferred(internal, owner.origin().immutable().ascii_serialization());
let value = MessagePort::new_transferred(internal);

// Step 2
let owner = unsafe { GlobalScope::from_context(cx) };
let message_port = reflect_dom_object(Box::new(value), &*owner, Wrap);

{
@@ -321,6 +310,7 @@ impl MessagePortMethods for MessagePort {

// Step 7
let task = PortMessageTask {
origin: self.global().origin().immutable().ascii_serialization(),
data,
};

@@ -101,13 +101,16 @@ impl ServiceWorkerMethods for ServiceWorker {
// Step 7
rooted!(in(cx) let transfer = UndefinedValue());
let data = StructuredCloneData::write(cx, message, transfer.handle())?;
let msg_vec = DOMMessage(data.move_to_arraybuffer());
let msg_vec = DOMMessage {
origin: self.global().origin().immutable().ascii_serialization(),
data: data.move_to_arraybuffer(),
};
let _ = self
.global()
.script_to_constellation_chan()
.send(ScriptMsg::ForwardDOMMessage(
msg_vec,
self.scope_url.clone(),
self.scope_url.clone()
));
Ok(())
}
@@ -407,7 +407,7 @@ impl ServiceWorkerGlobalScope {
use self::ServiceWorkerScriptMsg::*;

match msg {
CommonWorker(WorkerScriptMsg::DOMMessage(data)) => {
CommonWorker(WorkerScriptMsg::DOMMessage { data, .. }) => {
let scope = self.upcast::<WorkerGlobalScope>();
let target = self.upcast();
let _ac = JSAutoRealm::new(scope.get_cx(), scope.reflector().get_jsobject().get());
@@ -2210,10 +2210,11 @@ impl Window {
let task = task!(post_serialised_message: move || {
let this = this.root();
let source = source.root();
let document = this.Document();

// Step 7.1.
if let Some(target_origin) = target_origin {
if !target_origin.same_origin(this.Document().origin()) {
if let Some(ref target_origin) = target_origin {
if !target_origin.same_origin(document.origin()) {
return;
}
}
@@ -2239,7 +2240,7 @@ impl Window {
this.upcast(),
this.upcast(),
message_clone.handle(),
None,
Some(&document.origin().immutable().ascii_serialization()),
Some(&*source),
new_ports,
);
@@ -135,7 +135,11 @@ impl Worker {
self.terminated.get()
}

pub fn handle_message(address: TrustedWorkerAddress, data: StructuredCloneData) {
pub fn handle_message(
address: TrustedWorkerAddress,
origin: String,
data: StructuredCloneData,
) {
let worker = address.root();

if worker.is_terminated() {
@@ -147,7 +151,7 @@ impl Worker {
let _ac = JSAutoRealm::new(global.get_cx(), target.reflector().get_jsobject().get());
rooted!(in(global.get_cx()) let mut message = UndefinedValue());
assert!(data.read(&global, message.handle_mut()));
MessageEvent::dispatch_jsval(target, &global, message.handle(), None, None, vec![]);
MessageEvent::dispatch_jsval(target, &global, message.handle(), Some(&origin), None, vec![]);
}

pub fn dispatch_simple_error(address: TrustedWorkerAddress) {
@@ -168,7 +172,10 @@ impl WorkerMethods for Worker {
// indicates that a nonexistent communication channel should result in a silent error.
let _ = self.sender.send(DedicatedWorkerScriptMsg::CommonWorker(
address,
WorkerScriptMsg::DOMMessage(data),
WorkerScriptMsg::DOMMessage {
origin: self.global().origin().immutable().ascii_serialization(),
data,
},
));
Ok(())
}
@@ -135,10 +135,10 @@ impl ServiceWorkerManager {
}

fn forward_message(&self, msg: DOMMessage, sender: &Sender<ServiceWorkerScriptMsg>) {
let DOMMessage(data) = msg;
let DOMMessage { origin, data } = msg;
let data = StructuredCloneData::Vector(data);
let _ = sender.send(ServiceWorkerScriptMsg::CommonWorker(
WorkerScriptMsg::DOMMessage(data),
WorkerScriptMsg::DOMMessage { origin, data },
));
}

@@ -278,7 +278,12 @@ pub struct ScopeThings {

/// Message that gets passed to service worker scope on postMessage
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct DOMMessage(pub Vec<u8>);
pub struct DOMMessage {
/// The origin of the message
pub origin: String,
/// The payload of the message
pub data: Vec<u8>,
}

/// Channels to allow service worker manager to communicate with constellation and resource thread
pub struct SWManagerSenders {
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.