use {io, poll, Evented, Ready, Poll, PollOpt, Token}; use zircon; use std::sync::{Arc, Mutex, Weak}; pub struct Awakener { /// Token and weak reference to the port on which Awakener was registered. /// /// When `Awakener::wakeup` is called, these are used to send a wakeup message to the port. inner: Mutex)>>, } impl Awakener { /// Create a new `Awakener`. pub fn new() -> io::Result { Ok(Awakener { inner: Mutex::new(None) }) } /// Send a wakeup signal to the `Selector` on which the `Awakener` was registered. pub fn wakeup(&self) -> io::Result<()> { let inner_locked = self.inner.lock().unwrap(); let &(token, ref weak_port) = inner_locked.as_ref().expect("Called wakeup on unregistered awakener."); let port = weak_port.upgrade().expect("Tried to wakeup a closed port."); let status = 0; // arbitrary let packet = zircon::Packet::from_user_packet( token.0 as u64, status, zircon::UserPacket::from_u8_array([0; 32])); Ok(port.queue(&packet)?) } pub fn cleanup(&self) {} } impl Evented for Awakener { fn register(&self, poll: &Poll, token: Token, _events: Ready, _opts: PollOpt) -> io::Result<()> { let mut inner_locked = self.inner.lock().unwrap(); if inner_locked.is_some() { panic!("Called register on already-registered Awakener."); } *inner_locked = Some((token, Arc::downgrade(poll::selector(poll).port()))); Ok(()) } fn reregister(&self, poll: &Poll, token: Token, _events: Ready, _opts: PollOpt) -> io::Result<()> { let mut inner_locked = self.inner.lock().unwrap(); *inner_locked = Some((token, Arc::downgrade(poll::selector(poll).port()))); Ok(()) } fn deregister(&self, _poll: &Poll) -> io::Result<()> { let mut inner_locked = self.inner.lock().unwrap(); *inner_locked = None; Ok(()) } }