-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rt: add Runtime::shutdown_timeout
#2186
Changes from all commits
d79fb63
f0de4b4
2c77f19
75c7d67
cdb99b0
417d20d
a52ed8d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -101,19 +101,30 @@ impl BlockingPool { | |
pub(crate) fn spawner(&self) -> &Spawner { | ||
&self.spawner | ||
} | ||
} | ||
|
||
impl Drop for BlockingPool { | ||
fn drop(&mut self) { | ||
pub(crate) fn shutdown(&mut self, timeout: Option<Duration>) { | ||
let mut shared = self.spawner.inner.shared.lock().unwrap(); | ||
|
||
// The function can be called multiple times. First, by explicitly | ||
// calling `shutdown` then by the drop handler calling `shutdown`. This | ||
// prevents shutting down twice. | ||
if shared.shutdown { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The function can be called multiple times. First, by explicitly calling There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Might be good if there was a comment in the code stating that, as well as on the PR? |
||
return; | ||
} | ||
|
||
shared.shutdown = true; | ||
shared.shutdown_tx = None; | ||
self.spawner.inner.condvar.notify_all(); | ||
|
||
drop(shared); | ||
|
||
self.shutdown_rx.wait(); | ||
self.shutdown_rx.wait(timeout); | ||
} | ||
} | ||
|
||
impl Drop for BlockingPool { | ||
fn drop(&mut self) { | ||
self.shutdown(None); | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -75,6 +75,7 @@ pub(crate) fn exit<F: FnOnce() -> R, R>(f: F) -> R { | |
|
||
cfg_blocking_impl! { | ||
use crate::park::ParkError; | ||
use std::time::Duration; | ||
|
||
impl Enter { | ||
/// Blocks the thread on the specified future, returning the value with | ||
|
@@ -104,6 +105,44 @@ cfg_blocking_impl! { | |
park.park()?; | ||
} | ||
} | ||
|
||
/// Blocks the thread on the specified future for **at most** `timeout` | ||
/// | ||
/// If the future completes before `timeout`, the result is returned. If | ||
/// `timeout` elapses, then `Err` is returned. | ||
pub(crate) fn block_on_timeout<F>(&mut self, mut f: F, timeout: Duration) -> Result<F::Output, ParkError> | ||
where | ||
F: std::future::Future, | ||
{ | ||
use crate::park::{CachedParkThread, Park}; | ||
use std::pin::Pin; | ||
use std::task::Context; | ||
use std::task::Poll::Ready; | ||
Comment on lines
+117
to
+120
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. minor style nit: some of these imports are now used by both |
||
use std::time::Instant; | ||
|
||
let mut park = CachedParkThread::new(); | ||
let waker = park.get_unpark()?.into_waker(); | ||
let mut cx = Context::from_waker(&waker); | ||
|
||
// `block_on` takes ownership of `f`. Once it is pinned here, the original `f` binding can | ||
// no longer be accessed, making the pinning safe. | ||
let mut f = unsafe { Pin::new_unchecked(&mut f) }; | ||
let when = Instant::now() + timeout; | ||
|
||
loop { | ||
if let Ready(v) = f.as_mut().poll(&mut cx) { | ||
return Ok(v); | ||
} | ||
|
||
let now = Instant::now(); | ||
|
||
if now >= when { | ||
return Err(()); | ||
} | ||
|
||
park.park_timeout(when - now)?; | ||
} | ||
} | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reshuffling internal code. This used to be public, which is why
ParkError
is opaque.