ethcore-io retries failed work steal (#9651)
* ethcore-io uses newer version of crossbeam && retries failed work steal * ethcore-io non-mio service uses newer crossbeam
This commit is contained in:
parent
2d44b3ebea
commit
ebaa43fa4c
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -600,7 +600,7 @@ version = "1.12.0"
|
||||
name = "ethcore-io"
|
||||
version = "1.12.0"
|
||||
dependencies = [
|
||||
"crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam-deque 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2296,7 +2296,7 @@ source = "git+https://github.com/nikvolf/parity-tokio-ipc#c0f80b40399d7f08ef1e68
|
||||
dependencies = [
|
||||
"bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio-named-pipes 0.1.6 (git+https://github.com/alexcrichton/mio-named-pipes)",
|
||||
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -693,7 +693,6 @@ impl Engine<EthereumMachine> for Tendermint {
|
||||
}
|
||||
|
||||
fn stop(&self) {
|
||||
self.step_service.stop()
|
||||
}
|
||||
|
||||
fn is_proposal(&self, header: &Header) -> bool {
|
||||
|
@ -9,7 +9,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
||||
[dependencies]
|
||||
fnv = "1.0"
|
||||
mio = { version = "0.6.8", optional = true }
|
||||
crossbeam = "0.3"
|
||||
crossbeam-deque = "0.6"
|
||||
parking_lot = "0.6"
|
||||
log = "0.4"
|
||||
slab = "0.4"
|
||||
|
@ -74,7 +74,7 @@ extern crate mio;
|
||||
#[macro_use]
|
||||
extern crate log as rlog;
|
||||
extern crate slab;
|
||||
extern crate crossbeam;
|
||||
extern crate crossbeam_deque as deque;
|
||||
extern crate parking_lot;
|
||||
extern crate num_cpus;
|
||||
extern crate timer;
|
||||
|
@ -20,7 +20,7 @@ use std::collections::HashMap;
|
||||
use mio::*;
|
||||
use mio::timer::{Timeout};
|
||||
use mio::deprecated::{EventLoop, Handler, Sender, EventLoopBuilder};
|
||||
use crossbeam::sync::chase_lev;
|
||||
use deque;
|
||||
use slab::Slab;
|
||||
use {IoError, IoHandler};
|
||||
use worker::{Worker, Work, WorkType};
|
||||
@ -184,7 +184,7 @@ pub struct IoManager<Message> where Message: Send + Sync {
|
||||
timers: Arc<RwLock<HashMap<HandlerId, UserTimer>>>,
|
||||
handlers: Arc<RwLock<Slab<Arc<IoHandler<Message>>>>>,
|
||||
workers: Vec<Worker>,
|
||||
worker_channel: chase_lev::Worker<Work<Message>>,
|
||||
worker_channel: deque::Worker<Work<Message>>,
|
||||
work_ready: Arc<Condvar>,
|
||||
}
|
||||
|
||||
@ -194,7 +194,7 @@ impl<Message> IoManager<Message> where Message: Send + Sync + 'static {
|
||||
event_loop: &mut EventLoop<IoManager<Message>>,
|
||||
handlers: Arc<RwLock<Slab<Arc<IoHandler<Message>>>>>
|
||||
) -> Result<(), IoError> {
|
||||
let (worker, stealer) = chase_lev::deque();
|
||||
let (worker, stealer) = deque::fifo();
|
||||
let num_workers = 4;
|
||||
let work_ready_mutex = Arc::new(Mutex::new(()));
|
||||
let work_ready = Arc::new(Condvar::new());
|
||||
@ -430,7 +430,7 @@ impl<Message> IoChannel<Message> where Message: Send + Sync + 'static {
|
||||
/// General IO Service. Starts an event loop and dispatches IO requests.
|
||||
/// 'Message' is a notification message type
|
||||
pub struct IoService<Message> where Message: Send + Sync + 'static {
|
||||
thread: Mutex<Option<JoinHandle<()>>>,
|
||||
thread: Option<JoinHandle<()>>,
|
||||
host_channel: Mutex<Sender<IoMessage<Message>>>,
|
||||
handlers: Arc<RwLock<Slab<Arc<IoHandler<Message>>>>>,
|
||||
}
|
||||
@ -448,19 +448,19 @@ impl<Message> IoService<Message> where Message: Send + Sync + 'static {
|
||||
IoManager::<Message>::start(&mut event_loop, h).expect("Error starting IO service");
|
||||
});
|
||||
Ok(IoService {
|
||||
thread: Mutex::new(Some(thread)),
|
||||
thread: Some(thread),
|
||||
host_channel: Mutex::new(channel),
|
||||
handlers: handlers,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn stop(&self) {
|
||||
pub fn stop(&mut self) {
|
||||
trace!(target: "shutdown", "[IoService] Closing...");
|
||||
// Clear handlers so that shared pointers are not stuck on stack
|
||||
// in Channel::send_sync
|
||||
self.handlers.write().clear();
|
||||
self.host_channel.lock().send(IoMessage::Shutdown).unwrap_or_else(|e| warn!("Error on IO service shutdown: {:?}", e));
|
||||
if let Some(thread) = self.thread.lock().take() {
|
||||
if let Some(thread) = self.thread.take() {
|
||||
thread.join().unwrap_or_else(|e| {
|
||||
debug!(target: "shutdown", "Error joining IO service event loop thread: {:?}", e);
|
||||
});
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
use std::sync::{Arc, Weak};
|
||||
use std::thread;
|
||||
use crossbeam::sync::chase_lev;
|
||||
use deque;
|
||||
use slab::Slab;
|
||||
use fnv::FnvHashMap;
|
||||
use {IoError, IoHandler};
|
||||
@ -198,7 +198,7 @@ struct Shared<Message> where Message: Send + Sync + 'static {
|
||||
// necessary.
|
||||
timers: Mutex<FnvHashMap<TimerToken, TimerGuard>>,
|
||||
// Channel used to send work to the worker threads.
|
||||
channel: Mutex<Option<chase_lev::Worker<WorkTask<Message>>>>,
|
||||
channel: Mutex<Option<deque::Worker<WorkTask<Message>>>>,
|
||||
}
|
||||
|
||||
// Messages used to communicate with the event loop from other threads.
|
||||
@ -224,7 +224,7 @@ impl<Message> Clone for WorkTask<Message> where Message: Send + Sized {
|
||||
impl<Message> IoService<Message> where Message: Send + Sync + 'static {
|
||||
/// Starts IO event loop
|
||||
pub fn start() -> Result<IoService<Message>, IoError> {
|
||||
let (tx, rx) = chase_lev::deque();
|
||||
let (tx, rx) = deque::fifo();
|
||||
|
||||
let shared = Arc::new(Shared {
|
||||
handlers: RwLock::new(Slab::with_capacity(MAX_HANDLERS)),
|
||||
@ -251,7 +251,7 @@ impl<Message> IoService<Message> where Message: Send + Sync + 'static {
|
||||
}
|
||||
|
||||
/// Stops the IO service.
|
||||
pub fn stop(&self) {
|
||||
pub fn stop(&mut self) {
|
||||
trace!(target: "shutdown", "[IoService] Closing...");
|
||||
// Clear handlers so that shared pointers are not stuck on stack
|
||||
// in Channel::send_sync
|
||||
@ -307,15 +307,15 @@ impl<Message> Drop for IoService<Message> where Message: Send + Sync {
|
||||
}
|
||||
}
|
||||
|
||||
fn do_work<Message>(shared: &Arc<Shared<Message>>, rx: chase_lev::Stealer<WorkTask<Message>>)
|
||||
where Message: Send + Sync + 'static
|
||||
fn do_work<Message>(shared: &Arc<Shared<Message>>, rx: deque::Stealer<WorkTask<Message>>)
|
||||
where Message: Send + Sync + 'static
|
||||
{
|
||||
loop {
|
||||
match rx.steal() {
|
||||
chase_lev::Steal::Abort => continue,
|
||||
chase_lev::Steal::Empty => thread::park(),
|
||||
chase_lev::Steal::Data(WorkTask::Shutdown) => break,
|
||||
chase_lev::Steal::Data(WorkTask::UserMessage(message)) => {
|
||||
deque::Steal::Retry => continue,
|
||||
deque::Steal::Empty => thread::park(),
|
||||
deque::Steal::Data(WorkTask::Shutdown) => break,
|
||||
deque::Steal::Data(WorkTask::UserMessage(message)) => {
|
||||
for id in 0 .. MAX_HANDLERS {
|
||||
if let Some(handler) = shared.handlers.read().get(id) {
|
||||
let ctxt = IoContext { handler: id, shared: shared.clone() };
|
||||
@ -323,7 +323,7 @@ fn do_work<Message>(shared: &Arc<Shared<Message>>, rx: chase_lev::Stealer<WorkTa
|
||||
}
|
||||
}
|
||||
},
|
||||
chase_lev::Steal::Data(WorkTask::TimerTrigger { handler_id, token }) => {
|
||||
deque::Steal::Data(WorkTask::TimerTrigger { handler_id, token }) => {
|
||||
if let Some(handler) = shared.handlers.read().get(handler_id) {
|
||||
let ctxt = IoContext { handler: handler_id, shared: shared.clone() };
|
||||
handler.timeout(&ctxt, token);
|
||||
|
@ -17,7 +17,7 @@
|
||||
use std::sync::Arc;
|
||||
use std::thread::{JoinHandle, self};
|
||||
use std::sync::atomic::{AtomicBool, Ordering as AtomicOrdering};
|
||||
use crossbeam::sync::chase_lev;
|
||||
use deque;
|
||||
use service_mio::{HandlerId, IoChannel, IoContext};
|
||||
use IoHandler;
|
||||
use LOCAL_STACK_SIZE;
|
||||
@ -53,7 +53,7 @@ pub struct Worker {
|
||||
impl Worker {
|
||||
/// Creates a new worker instance.
|
||||
pub fn new<Message>(index: usize,
|
||||
stealer: chase_lev::Stealer<Work<Message>>,
|
||||
stealer: deque::Stealer<Work<Message>>,
|
||||
channel: IoChannel<Message>,
|
||||
wait: Arc<Condvar>,
|
||||
wait_mutex: Arc<Mutex<()>>,
|
||||
@ -75,8 +75,9 @@ impl Worker {
|
||||
worker
|
||||
}
|
||||
|
||||
fn work_loop<Message>(stealer: chase_lev::Stealer<Work<Message>>,
|
||||
channel: IoChannel<Message>, wait: Arc<Condvar>,
|
||||
fn work_loop<Message>(stealer: deque::Stealer<Work<Message>>,
|
||||
channel: IoChannel<Message>,
|
||||
wait: Arc<Condvar>,
|
||||
wait_mutex: Arc<Mutex<()>>,
|
||||
deleting: Arc<AtomicBool>)
|
||||
where Message: Send + Sync + 'static {
|
||||
@ -91,8 +92,9 @@ impl Worker {
|
||||
|
||||
while !deleting.load(AtomicOrdering::Acquire) {
|
||||
match stealer.steal() {
|
||||
chase_lev::Steal::Data(work) => Worker::do_work(work, channel.clone()),
|
||||
_ => break,
|
||||
deque::Steal::Data(work) => Worker::do_work(work, channel.clone()),
|
||||
deque::Steal::Retry => {},
|
||||
deque::Steal::Empty => break,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user