1 use {io, poll, Evented, Ready, Poll, PollOpt, Token}; 2 use zircon; 3 use std::sync::{Arc, Mutex, Weak}; 4 5 pub struct Awakener { 6 /// Token and weak reference to the port on which Awakener was registered. 7 /// 8 /// When `Awakener::wakeup` is called, these are used to send a wakeup message to the port. 9 inner: Mutex<Option<(Token, Weak<zircon::Port>)>>, 10 } 11 12 impl Awakener { 13 /// Create a new `Awakener`. new() -> io::Result<Awakener>14 pub fn new() -> io::Result<Awakener> { 15 Ok(Awakener { 16 inner: Mutex::new(None) 17 }) 18 } 19 20 /// Send a wakeup signal to the `Selector` on which the `Awakener` was registered. wakeup(&self) -> io::Result<()>21 pub fn wakeup(&self) -> io::Result<()> { 22 let inner_locked = self.inner.lock().unwrap(); 23 let &(token, ref weak_port) = 24 inner_locked.as_ref().expect("Called wakeup on unregistered awakener."); 25 26 let port = weak_port.upgrade().expect("Tried to wakeup a closed port."); 27 28 let status = 0; // arbitrary 29 let packet = zircon::Packet::from_user_packet( 30 token.0 as u64, status, zircon::UserPacket::from_u8_array([0; 32])); 31 32 Ok(port.queue(&packet)?) 33 } 34 cleanup(&self)35 pub fn cleanup(&self) {} 36 } 37 38 impl Evented for Awakener { register(&self, poll: &Poll, token: Token, _events: Ready, _opts: PollOpt) -> io::Result<()>39 fn register(&self, 40 poll: &Poll, 41 token: Token, 42 _events: Ready, 43 _opts: PollOpt) -> io::Result<()> 44 { 45 let mut inner_locked = self.inner.lock().unwrap(); 46 if inner_locked.is_some() { 47 panic!("Called register on already-registered Awakener."); 48 } 49 *inner_locked = Some((token, Arc::downgrade(poll::selector(poll).port()))); 50 51 Ok(()) 52 } 53 reregister(&self, poll: &Poll, token: Token, _events: Ready, _opts: PollOpt) -> io::Result<()>54 fn reregister(&self, 55 poll: &Poll, 56 token: Token, 57 _events: Ready, 58 _opts: PollOpt) -> io::Result<()> 59 { 60 let mut inner_locked = self.inner.lock().unwrap(); 61 *inner_locked = Some((token, Arc::downgrade(poll::selector(poll).port()))); 62 63 Ok(()) 64 } 65 deregister(&self, _poll: &Poll) -> io::Result<()>66 fn deregister(&self, _poll: &Poll) -> io::Result<()> 67 { 68 let mut inner_locked = self.inner.lock().unwrap(); 69 *inner_locked = None; 70 71 Ok(()) 72 } 73 }