mdrv/
driver.rs

1use std::mem;
2use std::thread::{self, JoinHandle};
3
4use ::channel::{channel, Sender};
5use ::proxy::{Proxy};
6
7use ::event_loop::{EventLoop};
8
9
10#[derive(Debug)]
11pub enum Error {}
12
13pub enum Tx {
14    Attach(Box<dyn Proxy + Send>),
15    Terminate,
16}
17
18pub struct Driver {
19    thr: Option<JoinHandle<()>>,
20    tx: Sender<Tx>,
21}
22
23impl Driver {
24    pub fn new() -> Result<Self, ::Error> {
25        let (tx, rx) = channel();
26        let thr = thread::spawn(move || {
27            EventLoop::new(rx).unwrap().run_forever(1024, None).unwrap();
28        });
29
30        Ok(Driver {
31            thr: Some(thr),
32            tx: tx,
33        })
34    }
35
36    pub fn attach(&mut self, proxy: Box<dyn Proxy + Send>) -> ::Result<()> {
37        match self.tx.send(Tx::Attach(proxy)) {
38            Ok(_) => Ok(()),
39            Err(err) => Err(::Error::Channel(err.into())),
40        }
41    }
42}
43
44impl Drop for Driver {
45    fn drop(&mut self) {
46        self.tx.send(Tx::Terminate).unwrap();
47        let thr = mem::replace(&mut self.thr, None).unwrap();
48        thr.join().unwrap();
49    }
50}
51
52
53#[cfg(test)]
54mod test {
55    use super::*;
56
57    use ::channel::{SinglePoll};
58    use ::proxy_handle::{ProxyWrapper, Handle};
59    use ::dummy::{self, wait_msgs, wait_close, DummyProxy, DummyHandle};
60
61    fn create_dummy() -> (
62        ProxyWrapper<DummyProxy, dummy::Tx, dummy::Rx>,
63        Handle<DummyHandle, dummy::Tx, dummy::Rx>,
64        SinglePoll,
65    ) {
66        let (p, h) = dummy::create().unwrap();
67        let sp = SinglePoll::new(&h.rx).unwrap();
68        (p, h, sp)
69    }
70
71    fn test_attach(
72        h: &mut Handle<DummyHandle, dummy::Tx, dummy::Rx>,
73        sp: &mut SinglePoll,
74    ) {
75        wait_msgs(h, sp, 1).unwrap();
76        assert_matches!(h.user.msgs.pop_front(), Some(dummy::Rx::Attached));
77        assert_matches!(h.user.msgs.pop_front(), None);
78    }
79
80    fn test_detach(
81        h: &mut Handle<DummyHandle, dummy::Tx, dummy::Rx>,
82        sp: &mut SinglePoll,
83    ) {
84        wait_close(h, sp).unwrap();
85        assert_matches!(h.user.msgs.pop_front(), Some(dummy::Rx::Detached));
86        assert_matches!(h.user.msgs.pop_front(), Some(dummy::Rx::Closed));
87        assert_matches!(h.user.msgs.pop_front(), None);
88    }
89
90    #[test]
91    fn add_remove() {
92        let mut drv = Driver::new().unwrap();
93        let (p, mut h, mut sp) = create_dummy();
94
95        drv.attach(Box::new(p)).unwrap();
96        test_attach(&mut h, &mut sp);
97
98        h.close().unwrap();
99        test_detach(&mut h, &mut sp);
100    }
101
102    #[test]
103    fn add_remove_multiple() {
104        let mut drv = Driver::new().unwrap();
105        let phs = (0..16).map(|_| create_dummy());
106        let mut hs = Vec::new();
107
108        for (p, h, sp) in phs {
109            drv.attach(Box::new(p)).unwrap();
110            hs.push((h, sp));
111        }
112
113        for (h, sp) in hs.iter_mut() {
114            test_attach(h, sp);
115        }
116
117        for (h, _) in hs.iter_mut() {
118            h.close().unwrap();
119        }
120
121        for (h, sp) in hs.iter_mut() {
122            test_detach(h, sp);
123        }
124
125        for (h, _) in hs.iter() {
126            assert_eq!(h.is_closed(), true);
127        }
128    }
129}