summaryrefslogtreecommitdiffstats
path: root/tokio/src/runtime
diff options
context:
space:
mode:
authorTaiki Endo <te316e89@gmail.com>2020-06-12 19:49:39 +0900
committerGitHub <noreply@github.com>2020-06-12 19:49:39 +0900
commit6b6e76080afc92450238df69c4edc12ee5f7518d (patch)
tree9ce5f612595a3829778df524c24f51a91f155a0e /tokio/src/runtime
parent68b4ca9f553bd4c26ea78e1f564e452071cf6474 (diff)
chore: reduce pin related unsafe code (#2613)
Diffstat (limited to 'tokio/src/runtime')
-rw-r--r--tokio/src/runtime/blocking/task.rs7
-rw-r--r--tokio/src/runtime/enter.rs14
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 {