Merge remote-tracking branch 'parity/master'
This commit is contained in:
@@ -7,7 +7,7 @@ version = "1.4.0"
|
||||
authors = ["Ethcore <admin@ethcore.io>"]
|
||||
|
||||
[dependencies]
|
||||
mio = { git = "https://github.com/ethcore/mio", branch = "v0.5.x" }
|
||||
mio = { git = "https://github.com/carllerche/mio" }
|
||||
crossbeam = "0.2"
|
||||
parking_lot = "0.3"
|
||||
log = "0.3"
|
||||
|
||||
@@ -65,7 +65,8 @@ mod service;
|
||||
mod worker;
|
||||
mod panics;
|
||||
|
||||
use mio::{EventLoop, Token};
|
||||
use mio::{Token};
|
||||
use mio::deprecated::{EventLoop, NotifyError};
|
||||
use std::fmt;
|
||||
|
||||
pub use worker::LOCAL_STACK_SIZE;
|
||||
@@ -96,8 +97,8 @@ impl From<::std::io::Error> for IoError {
|
||||
}
|
||||
}
|
||||
|
||||
impl<Message> From<::mio::NotifyError<service::IoMessage<Message>>> for IoError where Message: Send + Clone {
|
||||
fn from(_err: ::mio::NotifyError<service::IoMessage<Message>>) -> IoError {
|
||||
impl<Message> From<NotifyError<service::IoMessage<Message>>> for IoError where Message: Send + Clone {
|
||||
fn from(_err: NotifyError<service::IoMessage<Message>>) -> IoError {
|
||||
IoError::Mio(::std::io::Error::new(::std::io::ErrorKind::ConnectionAborted, "Network IO notification error"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,13 +18,16 @@ use std::sync::{Arc, Weak};
|
||||
use std::thread::{self, JoinHandle};
|
||||
use std::collections::HashMap;
|
||||
use mio::*;
|
||||
use mio::timer::{Timeout};
|
||||
use mio::deprecated::{EventLoop, Handler, Sender, EventLoopBuilder};
|
||||
use crossbeam::sync::chase_lev;
|
||||
use slab::Slab;
|
||||
use {IoError, IoHandler};
|
||||
use worker::{Worker, Work, WorkType};
|
||||
use panics::*;
|
||||
use parking_lot::{RwLock};
|
||||
use parking_lot::{RwLock, Mutex};
|
||||
use std::sync::{Condvar as SCondvar, Mutex as SMutex};
|
||||
use std::time::Duration;
|
||||
|
||||
/// Timer ID
|
||||
pub type TimerToken = usize;
|
||||
@@ -223,9 +226,9 @@ impl<Message> Handler for IoManager<Message> where Message: Send + Clone + Sync
|
||||
type Timeout = Token;
|
||||
type Message = IoMessage<Message>;
|
||||
|
||||
fn ready(&mut self, _event_loop: &mut EventLoop<Self>, token: Token, events: EventSet) {
|
||||
let handler_index = token.as_usize() / TOKENS_PER_HANDLER;
|
||||
let token_id = token.as_usize() % TOKENS_PER_HANDLER;
|
||||
fn ready(&mut self, _event_loop: &mut EventLoop<Self>, token: Token, events: Ready) {
|
||||
let handler_index = token.0 / TOKENS_PER_HANDLER;
|
||||
let token_id = token.0 % TOKENS_PER_HANDLER;
|
||||
if let Some(handler) = self.handlers.read().get(handler_index) {
|
||||
if events.is_hup() {
|
||||
self.worker_channel.push(Work { work_type: WorkType::Hup, token: token_id, handler: handler.clone(), handler_id: handler_index });
|
||||
@@ -243,15 +246,15 @@ impl<Message> Handler for IoManager<Message> where Message: Send + Clone + Sync
|
||||
}
|
||||
|
||||
fn timeout(&mut self, event_loop: &mut EventLoop<Self>, token: Token) {
|
||||
let handler_index = token.as_usize() / TOKENS_PER_HANDLER;
|
||||
let token_id = token.as_usize() % TOKENS_PER_HANDLER;
|
||||
let handler_index = token.0 / TOKENS_PER_HANDLER;
|
||||
let token_id = token.0 % TOKENS_PER_HANDLER;
|
||||
if let Some(handler) = self.handlers.read().get(handler_index) {
|
||||
if let Some(timer) = self.timers.read().get(&token.as_usize()) {
|
||||
if let Some(timer) = self.timers.read().get(&token.0) {
|
||||
if timer.once {
|
||||
self.timers.write().remove(&token_id);
|
||||
event_loop.clear_timeout(timer.timeout);
|
||||
event_loop.clear_timeout(&timer.timeout);
|
||||
} else {
|
||||
event_loop.timeout_ms(token, timer.delay).expect("Error re-registering user timer");
|
||||
event_loop.timeout(token, Duration::from_millis(timer.delay)).expect("Error re-registering user timer");
|
||||
}
|
||||
self.worker_channel.push(Work { work_type: WorkType::Timeout, token: token_id, handler: handler.clone(), handler_id: handler_index });
|
||||
self.work_ready.notify_all();
|
||||
@@ -277,18 +280,18 @@ impl<Message> Handler for IoManager<Message> where Message: Send + Clone + Sync
|
||||
let to_remove: Vec<_> = timers.keys().cloned().filter(|timer_id| timer_id / TOKENS_PER_HANDLER == handler_id).collect();
|
||||
for timer_id in to_remove {
|
||||
let timer = timers.remove(&timer_id).expect("to_remove only contains keys from timers; qed");
|
||||
event_loop.clear_timeout(timer.timeout);
|
||||
event_loop.clear_timeout(&timer.timeout);
|
||||
}
|
||||
},
|
||||
IoMessage::AddTimer { handler_id, token, delay, once } => {
|
||||
let timer_id = token + handler_id * TOKENS_PER_HANDLER;
|
||||
let timeout = event_loop.timeout_ms(Token(timer_id), delay).expect("Error registering user timer");
|
||||
let timeout = event_loop.timeout(Token(timer_id), Duration::from_millis(delay)).expect("Error registering user timer");
|
||||
self.timers.write().insert(timer_id, UserTimer { delay: delay, timeout: timeout, once: once });
|
||||
},
|
||||
IoMessage::RemoveTimer { handler_id, token } => {
|
||||
let timer_id = token + handler_id * TOKENS_PER_HANDLER;
|
||||
if let Some(timer) = self.timers.write().remove(&timer_id) {
|
||||
event_loop.clear_timeout(timer.timeout);
|
||||
event_loop.clear_timeout(&timer.timeout);
|
||||
}
|
||||
},
|
||||
IoMessage::RegisterStream { handler_id, token } => {
|
||||
@@ -302,7 +305,7 @@ impl<Message> Handler for IoManager<Message> where Message: Send + Clone + Sync
|
||||
// unregister a timer associated with the token (if any)
|
||||
let timer_id = token + handler_id * TOKENS_PER_HANDLER;
|
||||
if let Some(timer) = self.timers.write().remove(&timer_id) {
|
||||
event_loop.clear_timeout(timer.timeout);
|
||||
event_loop.clear_timeout(&timer.timeout);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -391,7 +394,7 @@ impl<Message> IoChannel<Message> where Message: Send + Clone + Sync + 'static {
|
||||
pub struct IoService<Message> where Message: Send + Sync + Clone + 'static {
|
||||
panic_handler: Arc<PanicHandler>,
|
||||
thread: Option<JoinHandle<()>>,
|
||||
host_channel: Sender<IoMessage<Message>>,
|
||||
host_channel: Mutex<Sender<IoMessage<Message>>>,
|
||||
handlers: Arc<RwLock<Slab<Arc<IoHandler<Message>>, HandlerId>>>,
|
||||
}
|
||||
|
||||
@@ -405,9 +408,9 @@ impl<Message> IoService<Message> where Message: Send + Sync + Clone + 'static {
|
||||
/// Starts IO event loop
|
||||
pub fn start() -> Result<IoService<Message>, IoError> {
|
||||
let panic_handler = PanicHandler::new_in_arc();
|
||||
let mut config = EventLoopConfig::new();
|
||||
let mut config = EventLoopBuilder::new();
|
||||
config.messages_per_tick(1024);
|
||||
let mut event_loop = EventLoop::configured(config).expect("Error creating event loop");
|
||||
let mut event_loop = config.build().expect("Error creating event loop");
|
||||
let channel = event_loop.channel();
|
||||
let panic = panic_handler.clone();
|
||||
let handlers = Arc::new(RwLock::new(Slab::new(MAX_HANDLERS)));
|
||||
@@ -421,14 +424,14 @@ impl<Message> IoService<Message> where Message: Send + Sync + Clone + 'static {
|
||||
Ok(IoService {
|
||||
panic_handler: panic_handler,
|
||||
thread: Some(thread),
|
||||
host_channel: channel,
|
||||
host_channel: Mutex::new(channel),
|
||||
handlers: handlers,
|
||||
})
|
||||
}
|
||||
|
||||
/// Regiter an IO handler with the event loop.
|
||||
pub fn register_handler(&self, handler: Arc<IoHandler<Message>+Send>) -> Result<(), IoError> {
|
||||
try!(self.host_channel.send(IoMessage::AddHandler {
|
||||
try!(self.host_channel.lock().send(IoMessage::AddHandler {
|
||||
handler: handler,
|
||||
}));
|
||||
Ok(())
|
||||
@@ -436,20 +439,20 @@ impl<Message> IoService<Message> where Message: Send + Sync + Clone + 'static {
|
||||
|
||||
/// Send a message over the network. Normaly `HostIo::send` should be used. This can be used from non-io threads.
|
||||
pub fn send_message(&self, message: Message) -> Result<(), IoError> {
|
||||
try!(self.host_channel.send(IoMessage::UserMessage(message)));
|
||||
try!(self.host_channel.lock().send(IoMessage::UserMessage(message)));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Create a new message channel
|
||||
pub fn channel(&self) -> IoChannel<Message> {
|
||||
IoChannel::new(self.host_channel.clone(), Arc::downgrade(&self.handlers))
|
||||
IoChannel::new(self.host_channel.lock().clone(), Arc::downgrade(&self.handlers))
|
||||
}
|
||||
}
|
||||
|
||||
impl<Message> Drop for IoService<Message> where Message: Send + Sync + Clone {
|
||||
fn drop(&mut self) {
|
||||
trace!(target: "shutdown", "[IoService] Closing...");
|
||||
self.host_channel.send(IoMessage::Shutdown).unwrap_or_else(|e| warn!("Error on IO service shutdown: {:?}", e));
|
||||
self.host_channel.lock().send(IoMessage::Shutdown).unwrap_or_else(|e| warn!("Error on IO service shutdown: {:?}", e));
|
||||
self.thread.take().unwrap().join().ok();
|
||||
trace!(target: "shutdown", "[IoService] Closed.");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user