diff options
author | Carl Lerche <me@carllerche.com> | 2019-12-22 13:03:44 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-12-22 13:03:44 -0800 |
commit | adc5186ebd1290c2f144e153a87e147d257f8b0f (patch) | |
tree | 507624871353d166db8e822208d06e873ea8611f /tokio/src/park | |
parent | 7b53b7b659fe1feeb30e768cad8fdadf9531beb6 (diff) |
rt: fix storing Runtime in thread-local (#2011)
Storing a `Runtime` value in a thread-local resulted in a panic due to
the inability to access the parker.
This fixes the bug by skipping parking if it fails. In general, there
isn't much that we can do besides not parking.
Fixes #593
Diffstat (limited to 'tokio/src/park')
-rw-r--r-- | tokio/src/park/mod.rs | 2 | ||||
-rw-r--r-- | tokio/src/park/thread.rs | 15 |
2 files changed, 11 insertions, 6 deletions
diff --git a/tokio/src/park/mod.rs b/tokio/src/park/mod.rs index 9c1958c3..13dfee2c 100644 --- a/tokio/src/park/mod.rs +++ b/tokio/src/park/mod.rs @@ -43,7 +43,7 @@ mod thread; pub(crate) use self::thread::ParkThread; cfg_blocking_impl! { - pub(crate) use self::thread::CachedParkThread; + pub(crate) use self::thread::{CachedParkThread, ParkError}; } use std::sync::Arc; diff --git a/tokio/src/park/thread.rs b/tokio/src/park/thread.rs index 59513e1d..853d4d8a 100644 --- a/tokio/src/park/thread.rs +++ b/tokio/src/park/thread.rs @@ -230,12 +230,17 @@ cfg_blocking_impl! { } } + pub(crate) fn get_unpark(&self) -> Result<UnparkThread, ParkError> { + self.with_current(|park_thread| park_thread.unpark()) + } + /// Get a reference to the `ParkThread` handle for this thread. - fn with_current<F, R>(&self, f: F) -> R + fn with_current<F, R>(&self, f: F) -> Result<R, ParkError> where F: FnOnce(&ParkThread) -> R, { - CURRENT_PARKER.with(|inner| f(inner)) + CURRENT_PARKER.try_with(|inner| f(inner)) + .map_err(|_| ParkError { _p: () }) } } @@ -244,16 +249,16 @@ cfg_blocking_impl! { type Error = ParkError; fn unpark(&self) -> Self::Unpark { - self.with_current(|park_thread| park_thread.unpark()) + self.get_unpark().unwrap() } fn park(&mut self) -> Result<(), Self::Error> { - self.with_current(|park_thread| park_thread.inner.park()); + self.with_current(|park_thread| park_thread.inner.park())?; Ok(()) } fn park_timeout(&mut self, duration: Duration) -> Result<(), Self::Error> { - self.with_current(|park_thread| park_thread.inner.park_timeout(duration)); + self.with_current(|park_thread| park_thread.inner.park_timeout(duration))?; Ok(()) } } |