/// General IO module. /// /// Example usage for craeting a network service and adding an IO handler: /// /// ```rust /// extern crate ethcore_util; /// use ethcore_util::*; /// /// struct MyHandler; /// /// struct MyMessage { /// data: u32 /// } /// /// impl IoHandler for MyHandler { /// fn initialize(&mut self, io: &mut IoContext) { /// io.register_timer(1000).unwrap(); /// } /// /// fn timeout(&mut self, _io: &mut IoContext, timer: TimerToken) { /// println!("Timeout {}", timer); /// } /// /// fn message(&mut self, _io: &mut IoContext, message: &mut MyMessage) { /// println!("Message {}", message.data); /// } /// } /// /// fn main () { /// let mut service = IoService::::start().expect("Error creating network service"); /// service.register_handler(Box::new(MyHandler)).unwrap(); /// /// // Wait for quit condition /// // ... /// // Drop the service /// } /// ``` mod service; mod worker; use mio::{EventLoop, Token}; #[derive(Debug)] pub enum IoError { Mio(::std::io::Error), } impl From<::mio::NotifyError>> for IoError where Message: Send + Clone { fn from(_err: ::mio::NotifyError>) -> IoError { IoError::Mio(::std::io::Error::new(::std::io::ErrorKind::ConnectionAborted, "Network IO notification error")) } } /// Generic IO handler. /// All the handler function are called from within IO event loop. /// `Message` type is used as notification data pub trait IoHandler: Send + Sync where Message: Send + Sync + Clone + 'static { /// Initialize the handler fn initialize(&self, _io: &IoContext) {} /// Timer function called after a timeout created with `HandlerIo::timeout`. fn timeout(&self, _io: &IoContext, _timer: TimerToken) {} /// Called when a broadcasted message is received. The message can only be sent from a different IO handler. fn message(&self, _io: &IoContext, _message: &Message) {} /// Called when an IO stream gets closed fn stream_hup(&self, _io: &IoContext, _stream: StreamToken) {} /// Called when an IO stream can be read from fn stream_readable(&self, _io: &IoContext, _stream: StreamToken) {} /// Called when an IO stream can be written to fn stream_writable(&self, _io: &IoContext, _stream: StreamToken) {} /// Register a new stream with the event loop fn register_stream(&self, _stream: StreamToken, _reg: Token, _event_loop: &mut EventLoop>) {} /// Re-register a stream with the event loop fn update_stream(&self, _stream: StreamToken, _reg: Token, _event_loop: &mut EventLoop>) {} } pub type TimerToken = service::TimerToken; pub type StreamToken = service::StreamToken; pub use io::service::IoContext; pub type IoService = service::IoService; pub type IoChannel = service::IoChannel; pub type IoManager = service::IoManager; pub const TOKENS_PER_HANDLER: usize = service::TOKENS_PER_HANDLER; #[cfg(test)] mod tests { use io::*; struct MyHandler; struct MyMessage { data: u32 } impl IoHandler for MyHandler { fn initialize(&mut self, io: &mut IoContext) { io.register_timer(1000).unwrap(); } fn timeout(&mut self, _io: &mut IoContext, timer: TimerToken) { println!("Timeout {}", timer); } fn message(&mut self, _io: &mut IoContext, message: &mut MyMessage) { println!("Message {}", message.data); } } #[test] fn test_service_register_handler () { let mut service = IoService::::start().expect("Error creating network service"); service.register_handler(Box::new(MyHandler)).unwrap(); } }