diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index eca2bf4..9b517de 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -20,6 +20,7 @@ serde1 = ["trace/serde", "serde", "serde/derive"] fnv = "1.0" humantime = "1.0" log = "0.4" +parking_lot = "0.7" pin-utils = "0.1.0-alpha.4" rand = "0.6" tokio-timer = "0.2" diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index dc87d8c..b4e5fe3 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -45,7 +45,8 @@ use futures::{ task::{Poll, Spawn, SpawnError, SpawnExt}, Future, }; -use std::{cell::RefCell, io, sync::Once, time::SystemTime}; +use std::{cell::RefCell, io, sync::{Arc, Once}, time::SystemTime}; +use parking_lot::Mutex; /// A message from a client to a server. #[derive(Debug)] @@ -149,9 +150,9 @@ impl Request { pub(crate) type PollIo = Poll>>; static INIT: Once = Once::new(); -static mut SEED_SPAWN: Option> = None; +static mut SEED_SPAWN: Option>> = None; thread_local! { - static SPAWN: RefCell> = { + static SPAWN: RefCell>> = { unsafe { // INIT must always be called before accessing SPAWN. // Otherwise, accessing SPAWN can trigger undefined behavior due to race conditions. @@ -166,30 +167,14 @@ thread_local! { /// /// Init only has an effect the first time it is called. If called previously, successive calls to /// init are noops. -pub fn init(spawn: impl Spawn + Clone + 'static) { +pub fn init(spawn: impl Spawn + 'static) { unsafe { INIT.call_once(|| { - SEED_SPAWN = Some(Box::new(spawn)); + SEED_SPAWN = Some(Arc::new(Mutex::new(spawn))); }); } } pub(crate) fn spawn(future: impl Future + Send + 'static) -> Result<(), SpawnError> { - SPAWN.with(|spawn| spawn.borrow_mut().spawn(future)) -} - -trait CloneSpawn: Spawn { - fn box_clone(&self) -> Box; -} - -impl Clone for Box { - fn clone(&self) -> Self { - self.box_clone() - } -} - -impl CloneSpawn for S { - fn box_clone(&self) -> Box { - Box::new(self.clone()) - } + SPAWN.with(|spawn| spawn.borrow_mut().lock().spawn(future)) }