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}