From 7925642b1be684124449288b732fdba217f40e64 Mon Sep 17 00:00:00 2001 From: Tomusdrw Date: Wed, 10 Feb 2016 15:28:43 +0100 Subject: [PATCH] Removing overengineered stuff --- ethcore/src/block_queue.rs | 8 +-- ethcore/src/client.rs | 10 +-- parity/main.rs | 2 +- util/src/io/service.rs | 8 +-- util/src/io/worker.rs | 8 +-- util/src/panics.rs | 137 +++++++++++++------------------------ 6 files changed, 65 insertions(+), 108 deletions(-) diff --git a/ethcore/src/block_queue.rs b/ethcore/src/block_queue.rs index 389435a61..90f4338db 100644 --- a/ethcore/src/block_queue.rs +++ b/ethcore/src/block_queue.rs @@ -60,7 +60,7 @@ impl BlockQueueInfo { /// A queue of blocks. Sits between network or other I/O and the BlockChain. /// Sorts them ready for blockchain insertion. pub struct BlockQueue { - panic_handler: Arc, + panic_handler: Arc, engine: Arc>, more_to_verify: Arc, verification: Arc>, @@ -115,7 +115,7 @@ impl BlockQueue { let ready_signal = Arc::new(QueueSignal { signalled: AtomicBool::new(false), message_channel: message_channel }); let deleting = Arc::new(AtomicBool::new(false)); let empty = Arc::new(Condvar::new()); - let panic_handler = StringPanicHandler::new_arc(); + let panic_handler = PanicHandler::new_arc(); let mut verifiers: Vec> = Vec::new(); let thread_count = max(::num_cpus::get(), 3) - 2; @@ -337,8 +337,8 @@ impl BlockQueue { } } -impl MayPanic for BlockQueue { - fn on_panic(&self, closure: F) where F: OnPanicListener { +impl MayPanic for BlockQueue { + fn on_panic(&self, closure: F) where F: OnPanicListener { self.panic_handler.on_panic(closure); } } diff --git a/ethcore/src/client.rs b/ethcore/src/client.rs index 8a3b18d5c..92946b5ae 100644 --- a/ethcore/src/client.rs +++ b/ethcore/src/client.rs @@ -162,7 +162,7 @@ pub struct Client { block_queue: RwLock, report: RwLock, import_lock: Mutex<()>, - panic_handler: Arc, + panic_handler: Arc, } const HISTORY: u64 = 1000; @@ -211,9 +211,9 @@ impl Client { } let block_queue = BlockQueue::new(engine.clone(), message_channel); - let panic_handler = StringPanicHandler::new_arc(); + let panic_handler = PanicHandler::new_arc(); let panic = panic_handler.clone(); - block_queue.on_panic(move |t: &String| panic.notify_all(t)); + block_queue.on_panic(move |t| panic.notify_all(t)); Ok(Arc::new(Client { chain: chain, @@ -440,8 +440,8 @@ impl BlockChainClient for Client { } } -impl MayPanic for Client { - fn on_panic(&self, closure: F) where F: OnPanicListener { +impl MayPanic for Client { + fn on_panic(&self, closure: F) where F: OnPanicListener { self.panic_handler.on_panic(closure); } } diff --git a/parity/main.rs b/parity/main.rs index 50b1557a5..6d341a29f 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -169,7 +169,7 @@ fn wait_for_exit(client: Arc) { let e = exit.clone(); CtrlC::set_handler(move || { e.notify_all(); }); let e = exit.clone(); - client.on_panic(move |_t: &String| { e.notify_all(); }); + client.on_panic(move |_reason| { e.notify_all(); }); // Wait for signal let mutex = Mutex::new(()); let _ = exit.wait(mutex.lock().unwrap()).unwrap(); diff --git a/util/src/io/service.rs b/util/src/io/service.rs index f65619a66..c740a79c2 100644 --- a/util/src/io/service.rs +++ b/util/src/io/service.rs @@ -307,13 +307,13 @@ impl IoChannel where Message: Send + Clone { /// General IO Service. Starts an event loop and dispatches IO requests. /// 'Message' is a notification message type pub struct IoService where Message: Send + Sync + Clone + 'static { - panic_handler: Arc, + panic_handler: Arc, thread: Option>, host_channel: Sender>, } -impl MayPanic for IoService where Message: Send + Sync + Clone + 'static { - fn on_panic(&self, closure: F) where F: OnPanicListener { +impl MayPanic for IoService where Message: Send + Sync + Clone + 'static { + fn on_panic(&self, closure: F) where F: OnPanicListener { self.panic_handler.on_panic(closure); } } @@ -321,7 +321,7 @@ impl MayPanic for IoService where Message: Send + Sync impl IoService where Message: Send + Sync + Clone + 'static { /// Starts IO event loop pub fn start() -> Result, UtilError> { - let panic_handler = StringPanicHandler::new_arc(); + let panic_handler = PanicHandler::new_arc(); let mut event_loop = EventLoop::new().unwrap(); let channel = event_loop.channel(); let panic = panic_handler.clone(); diff --git a/util/src/io/worker.rs b/util/src/io/worker.rs index 33bb76bd7..6300dda2e 100644 --- a/util/src/io/worker.rs +++ b/util/src/io/worker.rs @@ -44,7 +44,7 @@ pub struct Worker { thread: Option>, wait: Arc, deleting: Arc, - panic_handler: Arc, + panic_handler: Arc, } impl Worker { @@ -55,7 +55,7 @@ impl Worker { wait: Arc, wait_mutex: Arc>) -> Worker where Message: Send + Sync + Clone + 'static { - let panic_handler = StringPanicHandler::new_arc(); + let panic_handler = PanicHandler::new_arc(); let deleting = Arc::new(AtomicBool::new(false)); let mut worker = Worker { panic_handler: panic_handler.clone(), @@ -114,8 +114,8 @@ impl Worker { } } -impl MayPanic for Worker { - fn on_panic(&self, closure: F) where F: OnPanicListener { +impl MayPanic for Worker { + fn on_panic(&self, closure: F) where F: OnPanicListener { self.panic_handler.on_panic(closure); } } diff --git a/util/src/panics.rs b/util/src/panics.rs index b618903b2..44bae9308 100644 --- a/util/src/panics.rs +++ b/util/src/panics.rs @@ -21,126 +21,83 @@ use std::ops::DerefMut; use std::any::Any; use std::sync::{Arc, Mutex}; -pub trait OnPanicListener: Send + Sync + 'static { - fn call(&mut self, arg: &T); +/// Thread-safe closure for handling possible panics +pub trait OnPanicListener: Send + Sync + 'static { + /// Invoke listener + fn call(&mut self, arg: &str); } -impl OnPanicListener for F - where F: FnMut(&T) + Send + Sync + 'static { - fn call(&mut self, arg: &T) { - self(arg) - } -} - -pub trait ArgsConverter : Send + Sync { - fn convert(&self, t: &Box) -> Option; -} - -pub trait MayPanic { +/// Trait indicating that the structure catches some of the panics (most probably from spawned threads) +/// and it's possbile to be notified when one of the threads panics. +pub trait MayPanic { + /// `closure` will be invoked whenever panic in thread is caught fn on_panic(&self, closure: F) - where F: OnPanicListener; + where F: OnPanicListener; } -pub trait PanicHandler> : MayPanic{ - fn with_converter(converter: C) -> Self; - fn catch_panic(&self, g: G) -> thread::Result - where G: FnOnce() -> R + Send + 'static; - fn notify_all(&self, &T); +/// Structure that allows to catch panics and notify listeners +pub struct PanicHandler { + listeners: Mutex>> } -pub struct StringConverter; -impl ArgsConverter for StringConverter { - fn convert(&self, t: &Box) -> Option { - let as_str = t.downcast_ref::<&'static str>().map(|t| t.clone().to_owned()); - let as_string = t.downcast_ref::().cloned(); - - as_str.or(as_string) +impl PanicHandler { + /// Creates new `PanicHandler` wrapped in `Arc` + pub fn new_arc() -> Arc { + Arc::new(Self::new()) } -} -pub struct BasePanicHandler - where C: ArgsConverter, T: 'static { - converter: C, - listeners: Mutex>>> -} - -impl PanicHandler for BasePanicHandler - where C: ArgsConverter, T: 'static { - - fn with_converter(converter: C) -> Self { - BasePanicHandler { - converter: converter, + /// Creates new `PanicHandler` + pub fn new() -> PanicHandler { + PanicHandler { listeners: Mutex::new(vec![]) } } + /// Invoke closure and catch any possible panics. + /// In case of panic notifies all listeners about it. #[allow(deprecated)] // TODO [todr] catch_panic is deprecated but panic::recover has different bounds (not allowing mutex) - fn catch_panic(&self, g: G) -> thread::Result where G: FnOnce() -> R + Send + 'static { + pub fn catch_panic(&self, g: G) -> thread::Result where G: FnOnce() -> R + Send + 'static { let result = thread::catch_panic(g); if let Err(ref e) = result { - let res = self.converter.convert(e); + let res = convert_to_string(e); if let Some(r) = res { - self.notify_all(&r); + self.notify_all(r); } } result } - fn notify_all(&self, r: &T) { + /// Notify listeners about panic + pub fn notify_all(&self, r: String) { let mut listeners = self.listeners.lock().unwrap(); for listener in listeners.deref_mut() { - listener.call(r); + listener.call(&r); } } } -impl MayPanic for BasePanicHandler - where C: ArgsConverter, T: 'static { +impl MayPanic for PanicHandler { fn on_panic(&self, closure: F) - where F: OnPanicListener { + where F: OnPanicListener { self.listeners.lock().unwrap().push(Box::new(closure)); } } -pub struct StringPanicHandler { - handler: BasePanicHandler -} - -impl StringPanicHandler { - pub fn new_arc() -> Arc { - Arc::new(Self::new()) - } - - pub fn new () -> Self { - Self::with_converter(StringConverter) +impl OnPanicListener for F + where F: FnMut(String) + Send + Sync + 'static { + fn call(&mut self, arg: &str) { + self(arg.to_owned()) } } -impl PanicHandler for StringPanicHandler { +fn convert_to_string(t: &Box) -> Option { + let as_str = t.downcast_ref::<&'static str>().map(|t| t.clone().to_owned()); + let as_string = t.downcast_ref::().cloned(); - fn with_converter(converter: StringConverter) -> Self { - StringPanicHandler { - handler: BasePanicHandler::with_converter(converter) - } - } - - fn catch_panic(&self, g: G) -> thread::Result where G: FnOnce() -> R + Send + 'static { - self.handler.catch_panic(g) - } - - fn notify_all(&self, r: &String) { - self.handler.notify_all(r); - } -} - -impl MayPanic for StringPanicHandler { - fn on_panic(&self, closure: F) - where F: OnPanicListener { - self.handler.on_panic(closure) - } + as_str.or(as_string) } #[test] @@ -149,8 +106,8 @@ fn should_notify_listeners_about_panic () { // given let invocations = Arc::new(RwLock::new(vec![])); let i = invocations.clone(); - let p = StringPanicHandler::new(); - p.on_panic(move |t: &String| i.write().unwrap().push(t.clone())); + let p = PanicHandler::new(); + p.on_panic(move |t| i.write().unwrap().push(t)); // when p.catch_panic(|| panic!("Panic!")).unwrap_err(); @@ -165,8 +122,8 @@ fn should_notify_listeners_about_panic_when_string_is_dynamic () { // given let invocations = Arc::new(RwLock::new(vec![])); let i = invocations.clone(); - let p = StringPanicHandler::new(); - p.on_panic(move |t: &String| i.write().unwrap().push(t.clone())); + let p = PanicHandler::new(); + p.on_panic(move |t| i.write().unwrap().push(t)); // when p.catch_panic(|| panic!("Panic: {}", 1)).unwrap_err(); @@ -183,8 +140,8 @@ fn should_notify_listeners_about_panic_in_other_thread () { // given let invocations = Arc::new(RwLock::new(vec![])); let i = invocations.clone(); - let p = StringPanicHandler::new(); - p.on_panic(move |t: &String| i.write().unwrap().push(t.clone())); + let p = PanicHandler::new(); + p.on_panic(move |t| i.write().unwrap().push(t)); // when let t = thread::spawn(move || @@ -202,11 +159,11 @@ use std::sync::RwLock; // given let invocations = Arc::new(RwLock::new(vec![])); let i = invocations.clone(); - let p = StringPanicHandler::new(); - p.on_panic(move |t: &String| i.write().unwrap().push(t.clone())); + let p = PanicHandler::new(); + p.on_panic(move |t| i.write().unwrap().push(t)); - let p2 = StringPanicHandler::new(); - p2.on_panic(move |t: &String| p.notify_all(t)); + let p2 = PanicHandler::new(); + p2.on_panic(move |t| p.notify_all(t)); // when p2.catch_panic(|| panic!("Panic!")).unwrap_err();