Skip to content

Commit

Permalink
Replace pin_project_lite with hand-rolled implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
NeoLegends committed Dec 15, 2020
1 parent 1fbc864 commit 6c00e3c
Showing 1 changed file with 43 additions and 48 deletions.
91 changes: 43 additions & 48 deletions tokio/src/task/task_local.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use pin_project_lite::pin_project;
use std::cell::RefCell;
use std::error::Error;
use std::future::Future;
Expand Down Expand Up @@ -175,34 +174,33 @@ impl<T: 'static> fmt::Debug for LocalKey<T> {
}
}

pin_project! {
/// A future that sets a value `T` of a task local for the future `F` during
/// its execution.
///
/// The value of the task-local must be `'static` and will be dropped on the
/// completion of the future.
///
/// Created by the function [`LocalKey::scope`](self::LocalKey::scope).
///
/// ### Examples
///
/// ```
/// # async fn dox() {
/// tokio::task_local! {
/// static NUMBER: u32;
/// }
///
/// NUMBER.scope(1, async move {
/// println!("task local value: {}", NUMBER.get());
/// }).await;
/// # }
/// ```
pub struct TaskLocalFuture<T: StaticLifetime, F> {
local: &'static LocalKey<T>,
slot: Option<T>,
#[pin]
future: F,
}
/// A future that sets a value `T` of a task local for the future `F` during
/// its execution.
///
/// The value of the task-local must be `'static` and will be dropped on the
/// completion of the future.
///
/// Created by the function [`LocalKey::scope`](self::LocalKey::scope).
///
/// ### Examples
///
/// ```
/// # async fn dox() {
/// tokio::task_local! {
/// static NUMBER: u32;
/// }
///
/// NUMBER.scope(1, async move {
/// println!("task local value: {}", NUMBER.get());
/// }).await;
/// # }
/// ```
#[must_use = "futures do nothing unless polled"]
#[derive(Debug)]
pub struct TaskLocalFuture<T: 'static, F> {
local: &'static LocalKey<T>,
slot: Option<T>,
future: F,
}

impl<T: 'static, F: Future> Future for TaskLocalFuture<T, F> {
Expand All @@ -222,31 +220,28 @@ impl<T: 'static, F: Future> Future for TaskLocalFuture<T, F> {
}
}

let mut project = self.project();
let val = project.slot.take();
unsafe {
let TaskLocalFuture {
local,
slot,
future,
} = self.get_unchecked_mut();

let prev = project.local.inner.with(|c| c.replace(val));
let val = slot.take();
let prev = local.inner.with(|c| c.replace(val));

let _guard = Guard {
prev,
slot: &mut project.slot,
local: *project.local,
};
let _guard = Guard {
prev,
slot,
local: &local,
};

project.future.poll(cx)
Pin::new_unchecked(future).poll(cx)
}
}
}

mod sealed {
pub trait Sealed {}

impl<T: 'static> Sealed for T {}
}

/// Required to make `pin_project` happy.
#[doc(hidden)]
pub trait StaticLifetime: self::sealed::Sealed + 'static {}
impl<T: 'static> StaticLifetime for T {}
impl<T: 'static, F: Unpin> Unpin for TaskLocalFuture<T, F> {}

/// An error returned by [`LocalKey::try_with`](method@LocalKey::try_with).
#[derive(Clone, Copy, Eq, PartialEq)]
Expand Down

0 comments on commit 6c00e3c

Please sign in to comment.