diff options
author | Taiki Endo <te316e89@gmail.com> | 2020-06-12 19:49:39 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-12 19:49:39 +0900 |
commit | 6b6e76080afc92450238df69c4edc12ee5f7518d (patch) | |
tree | 9ce5f612595a3829778df524c24f51a91f155a0e /tokio/src/runtime | |
parent | 68b4ca9f553bd4c26ea78e1f564e452071cf6474 (diff) |
chore: reduce pin related unsafe code (#2613)
Diffstat (limited to 'tokio/src/runtime')
-rw-r--r-- | tokio/src/runtime/blocking/task.rs | 7 | ||||
-rw-r--r-- | tokio/src/runtime/enter.rs | 14 |
2 files changed, 9 insertions, 12 deletions
diff --git a/tokio/src/runtime/blocking/task.rs b/tokio/src/runtime/blocking/task.rs index e0ae6e4e..a521af46 100644 --- a/tokio/src/runtime/blocking/task.rs +++ b/tokio/src/runtime/blocking/task.rs @@ -14,14 +14,17 @@ impl<T> BlockingTask<T> { } } +// The closure `F` is never pinned +impl<T> Unpin for BlockingTask<T> {} + impl<T, R> Future for BlockingTask<T> where T: FnOnce() -> R, { type Output = R; - fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<R> { - let me = unsafe { self.get_unchecked_mut() }; + fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<R> { + let me = &mut *self; let func = me .func .take() diff --git a/tokio/src/runtime/enter.rs b/tokio/src/runtime/enter.rs index ad5580cc..56a7c57b 100644 --- a/tokio/src/runtime/enter.rs +++ b/tokio/src/runtime/enter.rs @@ -142,12 +142,11 @@ cfg_block_on! { impl Enter { /// Blocks the thread on the specified future, returning the value with /// which that future completes. - pub(crate) fn block_on<F>(&mut self, mut f: F) -> Result<F::Output, crate::park::ParkError> + pub(crate) fn block_on<F>(&mut self, f: F) -> Result<F::Output, crate::park::ParkError> where F: std::future::Future, { use crate::park::{CachedParkThread, Park}; - use std::pin::Pin; use std::task::Context; use std::task::Poll::Ready; @@ -155,9 +154,7 @@ cfg_block_on! { 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) }; + pin!(f); loop { if let Ready(v) = crate::coop::budget(|| f.as_mut().poll(&mut cx)) { @@ -179,12 +176,11 @@ cfg_blocking_impl! { /// /// 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> + pub(crate) fn block_on_timeout<F>(&mut self, 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; use std::time::Instant; @@ -193,9 +189,7 @@ cfg_blocking_impl! { 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) }; + pin!(f); let when = Instant::now() + timeout; loop { |