aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/abstractworkerglobalscope.rs
blob: 7c79a9191654fca4e9fdd2ad24a5d13ef2f0820f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/* 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::DomObject;
use dom::bindings::trace::JSTraceable;
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: DomObject> {
    pub sender: Sender<(Trusted<T>, CommonScriptMsg)>,
    pub worker: Trusted<T>,
}

impl<T: JSTraceable + DomObject + '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: DomObject> {
    pub sender: Sender<(Trusted<T>, WorkerScriptMsg)>,
    pub worker: Trusted<T>,
}

impl<T: JSTraceable + DomObject + '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: DomObject> 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(()),
        }
    }
}