Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
implement related sw interface and register method
  • Loading branch information
creativcoder committed Jun 1, 2016
1 parent 0594d58 commit 15a2064
Show file tree
Hide file tree
Showing 33 changed files with 1,285 additions and 217 deletions.
1 change: 1 addition & 0 deletions components/profile/time.rs
Expand Up @@ -149,6 +149,7 @@ impl Formattable for ProfilerCategory {
ProfilerCategory::ScriptStylesheetLoad => "Script Stylesheet Load",
ProfilerCategory::ScriptWebSocketEvent => "Script Web Socket Event",
ProfilerCategory::ScriptWorkerEvent => "Script Worker Event",
ProfilerCategory::ScriptServiceWorkerEvent => "Script Service Worker Event",
ProfilerCategory::ApplicationHeartbeat => "Application Heartbeat",
};
format!("{}{}", padding, name)
Expand Down
1 change: 1 addition & 0 deletions components/profile_traits/time.rs
Expand Up @@ -80,6 +80,7 @@ pub enum ProfilerCategory {
ScriptUpdateReplacedElement,
ScriptWebSocketEvent,
ScriptWorkerEvent,
ScriptServiceWorkerEvent,
ApplicationHeartbeat,
}

Expand Down
104 changes: 104 additions & 0 deletions components/script/dom/abstractworker.rs
@@ -0,0 +1,104 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::refcounted::Trusted;
use dom::bindings::reflector::Reflectable;
use dom::bindings::str::DOMString;
use dom::bindings::structuredclone::StructuredCloneData;
use js::jsapi::{JSRuntime, JS_RequestInterruptCallback};
use js::rust::Runtime;
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
use net_traits::{LoadOrigin, RequestSource};
use script_runtime::CommonScriptMsg;
use url::Url;

/// Messages used to control the worker event loops
pub enum WorkerScriptMsg {
/// Common variants associated with the script messages
Common(CommonScriptMsg),
/// Message sent through Worker.postMessage
DOMMessage(StructuredCloneData),
}

#[derive(Clone)]
pub struct WorkerScriptLoadOrigin {
pub referrer_url: Option<Url>,
pub referrer_policy: Option<ReferrerPolicy>,
pub request_source: RequestSource,
pub pipeline_id: Option<PipelineId>
}

impl LoadOrigin for WorkerScriptLoadOrigin {
fn referrer_url(&self) -> Option<Url> {
self.referrer_url.clone()
}
fn referrer_policy(&self) -> Option<ReferrerPolicy> {
self.referrer_policy.clone()
}
fn request_source(&self) -> RequestSource {
self.request_source.clone()
}
fn pipeline_id(&self) -> Option<PipelineId> {
self.pipeline_id.clone()
}
}

pub struct SimpleWorkerErrorHandler<T: Reflectable> {
pub addr: Trusted<T>,
}

impl<T: Reflectable> SimpleWorkerErrorHandler<T> {
pub fn new(addr: Trusted<T>) -> SimpleWorkerErrorHandler<T> {
SimpleWorkerErrorHandler {
addr: addr
}
}
}

pub struct WorkerErrorHandler<T: Reflectable> {
pub addr: Trusted<T>,
pub msg: DOMString,
pub file_name: DOMString,
pub line_num: u32,
pub col_num: u32,
}

impl<T: Reflectable> WorkerErrorHandler<T> {
pub fn new(addr: Trusted<T>, msg: DOMString, file_name: DOMString, line_num: u32, col_num: u32)
-> WorkerErrorHandler<T> {
WorkerErrorHandler {
addr: addr,
msg: msg,
file_name: file_name,
line_num: line_num,
col_num: col_num,
}
}
}

#[derive(Copy, Clone)]
pub struct SharedRt {
pub rt: *mut JSRuntime
}

impl SharedRt {
pub fn new(rt: &Runtime) -> SharedRt {
SharedRt {
rt: rt.rt()
}
}

#[allow(unsafe_code)]
pub fn request_interrupt(&self) {
unsafe {
JS_RequestInterruptCallback(self.rt);
}
}

pub fn rt(&self) -> *mut JSRuntime {
self.rt
}
}
#[allow(unsafe_code)]
unsafe impl Send for SharedRt {}
65 changes: 65 additions & 0 deletions components/script/dom/abstractworkerglobalscope.rs
@@ -0,0 +1,65 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::abstractworker::WorkerScriptMsg;
use dom::bindings::refcounted::Trusted;
use dom::bindings::reflector::Reflectable;
use script_runtime::{ScriptChan, CommonScriptMsg, ScriptPort};
use std::sync::mpsc::{Receiver, Sender};

/// A ScriptChan that can be cloned freely and will silently send a TrustedWorkerAddress with
/// common event loop messages. While this SendableWorkerScriptChan is alive, the associated
/// Worker object will remain alive.
#[derive(JSTraceable, Clone)]
pub struct SendableWorkerScriptChan<T: Reflectable> {
pub sender: Sender<(Trusted<T>, CommonScriptMsg)>,
pub worker: Trusted<T>,
}

impl<T: Reflectable + 'static> ScriptChan for SendableWorkerScriptChan<T> {
fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> {
self.sender.send((self.worker.clone(), msg)).map_err(|_| ())
}

fn clone(&self) -> Box<ScriptChan + Send> {
box SendableWorkerScriptChan {
sender: self.sender.clone(),
worker: self.worker.clone(),
}
}
}

/// A ScriptChan that can be cloned freely and will silently send a TrustedWorkerAddress with
/// worker event loop messages. While this SendableWorkerScriptChan is alive, the associated
/// Worker object will remain alive.
#[derive(JSTraceable, Clone)]
pub struct WorkerThreadWorkerChan<T: Reflectable> {
pub sender: Sender<(Trusted<T>, WorkerScriptMsg)>,
pub worker: Trusted<T>,
}

impl<T: Reflectable + 'static> ScriptChan for WorkerThreadWorkerChan<T> {
fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> {
self.sender
.send((self.worker.clone(), WorkerScriptMsg::Common(msg)))
.map_err(|_| ())
}

fn clone(&self) -> Box<ScriptChan + Send> {
box WorkerThreadWorkerChan {
sender: self.sender.clone(),
worker: self.worker.clone(),
}
}
}

impl<T: Reflectable> ScriptPort for Receiver<(Trusted<T>, WorkerScriptMsg)> {
fn recv(&self) -> Result<CommonScriptMsg, ()> {
match self.recv().map(|(_, msg)| msg) {
Ok(WorkerScriptMsg::Common(script_msg)) => Ok(script_msg),
Ok(WorkerScriptMsg::DOMMessage(_)) => panic!("unexpected worker event message!"),
Err(_) => Err(()),
}
}
}
1 change: 1 addition & 0 deletions components/script/dom/bindings/str.rs
Expand Up @@ -81,6 +81,7 @@ impl ops::Deref for ByteString {

/// A string that is constructed from a UCS-2 buffer by replacing invalid code
/// points with the replacement character.
#[derive(Clone, HeapSizeOf)]
pub struct USVString(pub String);


Expand Down
7 changes: 5 additions & 2 deletions components/script/dom/bindings/trace.rs
Expand Up @@ -34,12 +34,12 @@ use canvas_traits::{CompositionOrBlending, LineCapStyle, LineJoinStyle, Repetiti
use cssparser::RGBA;
use devtools_traits::CSSError;
use devtools_traits::WorkerId;
use dom::abstractworker::SharedRt;
use dom::bindings::js::{JS, Root};
use dom::bindings::refcounted::Trusted;
use dom::bindings::reflector::{Reflectable, Reflector};
use dom::bindings::str::DOMString;
use dom::bindings::str::{DOMString, USVString};
use dom::bindings::utils::WindowProxyHandler;
use dom::worker::SharedRt;
use encoding::types::EncodingRef;
use euclid::length::Length as EuclidLength;
use euclid::matrix2d::Matrix2D;
Expand Down Expand Up @@ -81,6 +81,7 @@ use std::rc::Rc;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, AtomicUsize};
use std::sync::mpsc::{Receiver, Sender};
use std::time::SystemTime;
use string_cache::{Atom, Namespace, QualName};
use style::attr::{AttrIdentifier, AttrValue};
use style::element_state::*;
Expand Down Expand Up @@ -320,8 +321,10 @@ no_jsmanaged_fields!(ElementSnapshot);
no_jsmanaged_fields!(HttpsState);
no_jsmanaged_fields!(SharedRt);
no_jsmanaged_fields!(TouchpadPressurePhase);
no_jsmanaged_fields!(USVString);
no_jsmanaged_fields!(ReferrerPolicy);
no_jsmanaged_fields!(ResourceThreads);
no_jsmanaged_fields!(SystemTime);

impl JSTraceable for Box<ScriptChan + Send> {
#[inline]
Expand Down
59 changes: 59 additions & 0 deletions components/script/dom/client.rs
@@ -0,0 +1,59 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::codegen::Bindings::ClientBinding::FrameType;
use dom::bindings::codegen::Bindings::ClientBinding::{ClientMethods, Wrap};
use dom::bindings::global::GlobalRef;
use dom::bindings::js::JS;
use dom::bindings::js::Root;
use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::bindings::str::{DOMString, USVString};
use dom::serviceworker::ServiceWorker;
use dom::window::Window;
use url::Url;
use uuid::Uuid;

#[dom_struct]
pub struct Client {
reflector_: Reflector,
active_worker: Option<JS<ServiceWorker>>,
url: USVString,
frame_type: FrameType,
#[ignore_heap_size_of = "Defined in uuid"]
id: Uuid
}

impl Client {
fn new_inherited(url: Url) -> Client {
Client {
reflector_: Reflector::new(),
active_worker: None,
url: USVString(url.as_str().to_owned()),
frame_type: FrameType::None,
id: Uuid::new_v4()
}
}

pub fn new(window: &Window) -> Root<Client> {
reflect_dom_object(box Client::new_inherited(window.get_url()), GlobalRef::Window(window), Wrap)
}
}

impl ClientMethods for Client {
// https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#client-url-attribute
fn Url(&self) -> USVString {
self.url.clone()
}

// https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#client-frametype
fn FrameType(&self) -> FrameType {
self.frame_type
}

// https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#client-id
fn Id(&self) -> DOMString {
let uid_str = format!("{}", self.id);
DOMString::from_string(uid_str)
}
}
69 changes: 3 additions & 66 deletions components/script/dom/dedicatedworkerglobalscope.rs
Expand Up @@ -4,6 +4,8 @@

use devtools;
use devtools_traits::DevtoolScriptControlMsg;
use dom::abstractworker::{WorkerScriptLoadOrigin, WorkerScriptMsg, SharedRt , SimpleWorkerErrorHandler};
use dom::abstractworkerglobalscope::{SendableWorkerScriptChan, WorkerThreadWorkerChan};
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::DedicatedWorkerGlobalScopeBinding;
use dom::bindings::codegen::Bindings::DedicatedWorkerGlobalScopeBinding::DedicatedWorkerGlobalScopeMethods;
Expand All @@ -17,8 +19,7 @@ use dom::bindings::reflector::Reflectable;
use dom::bindings::str::DOMString;
use dom::bindings::structuredclone::StructuredCloneData;
use dom::messageevent::MessageEvent;
use dom::worker::{SimpleWorkerErrorHandler, SharedRt, TrustedWorkerAddress};
use dom::worker::{WorkerScriptLoadOrigin, WorkerMessageHandler};
use dom::worker::{TrustedWorkerAddress, WorkerMessageHandler};
use dom::workerglobalscope::WorkerGlobalScope;
use dom::workerglobalscope::WorkerGlobalScopeInit;
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
Expand All @@ -40,70 +41,6 @@ use url::Url;
use util::thread::spawn_named_with_send_on_panic;
use util::thread_state::{IN_WORKER, SCRIPT};

/// Messages used to control the worker event loops
pub enum WorkerScriptMsg {
/// Common variants associated with the script messages
Common(CommonScriptMsg),
/// Message sent through Worker.postMessage
DOMMessage(StructuredCloneData),
}

/// A ScriptChan that can be cloned freely and will silently send a TrustedWorkerAddress with
/// common event loop messages. While this SendableWorkerScriptChan is alive, the associated
/// Worker object will remain alive.
#[derive(JSTraceable, Clone)]
pub struct SendableWorkerScriptChan {
sender: Sender<(TrustedWorkerAddress, CommonScriptMsg)>,
worker: TrustedWorkerAddress,
}

impl ScriptChan for SendableWorkerScriptChan {
fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> {
self.sender.send((self.worker.clone(), msg)).map_err(|_| ())
}

fn clone(&self) -> Box<ScriptChan + Send> {
box SendableWorkerScriptChan {
sender: self.sender.clone(),
worker: self.worker.clone(),
}
}
}

/// A ScriptChan that can be cloned freely and will silently send a TrustedWorkerAddress with
/// worker event loop messages. While this SendableWorkerScriptChan is alive, the associated
/// Worker object will remain alive.
#[derive(JSTraceable, Clone)]
pub struct WorkerThreadWorkerChan {
sender: Sender<(TrustedWorkerAddress, WorkerScriptMsg)>,
worker: TrustedWorkerAddress,
}

impl ScriptChan for WorkerThreadWorkerChan {
fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> {
self.sender
.send((self.worker.clone(), WorkerScriptMsg::Common(msg)))
.map_err(|_| ())
}

fn clone(&self) -> Box<ScriptChan + Send> {
box WorkerThreadWorkerChan {
sender: self.sender.clone(),
worker: self.worker.clone(),
}
}
}

impl ScriptPort for Receiver<(TrustedWorkerAddress, WorkerScriptMsg)> {
fn recv(&self) -> Result<CommonScriptMsg, ()> {
match self.recv().map(|(_, msg)| msg) {
Ok(WorkerScriptMsg::Common(script_msg)) => Ok(script_msg),
Ok(WorkerScriptMsg::DOMMessage(_)) => panic!("unexpected worker event message!"),
Err(_) => Err(()),
}
}
}

/// Set the `worker` field of a related DedicatedWorkerGlobalScope object to a particular
/// value for the duration of this object's lifetime. This ensures that the related Worker
/// object only lives as long as necessary (ie. while events are being executed), while
Expand Down

0 comments on commit 15a2064

Please sign in to comment.