diff --git a/tokio-boring/src/async_callbacks.rs b/tokio-boring/src/async_callbacks.rs index 8fa9494b..94bd7c62 100644 --- a/tokio-boring/src/async_callbacks.rs +++ b/tokio-boring/src/async_callbacks.rs @@ -1,3 +1,4 @@ +use crate::mut_only::MutOnly; use boring::ex_data::Index; use boring::ssl::{self, ClientHello, PrivateKeyMethod, Ssl, SslContextBuilder}; use once_cell::sync::Lazy; @@ -29,17 +30,18 @@ pub type BoxGetSessionFinish = Box Option /// Convenience alias for futures stored in [`Ssl`] ex data by [`SslContextBuilderExt`] methods. /// /// Public for documentation purposes. -pub type ExDataFuture = Pin + Send + Sync>>; +pub type ExDataFuture = Pin + Send>>; pub(crate) static TASK_WAKER_INDEX: Lazy>> = Lazy::new(|| Ssl::new_ex_index().unwrap()); -pub(crate) static SELECT_CERT_FUTURE_INDEX: Lazy>> = +pub(crate) static SELECT_CERT_FUTURE_INDEX: Lazy>>> = Lazy::new(|| Ssl::new_ex_index().unwrap()); pub(crate) static SELECT_PRIVATE_KEY_METHOD_FUTURE_INDEX: Lazy< - Index>, + Index>>, +> = Lazy::new(|| Ssl::new_ex_index().unwrap()); +pub(crate) static SELECT_GET_SESSION_FUTURE_INDEX: Lazy< + Index>>, > = Lazy::new(|| Ssl::new_ex_index().unwrap()); -pub(crate) static SELECT_GET_SESSION_FUTURE_INDEX: Lazy>> = - Lazy::new(|| Ssl::new_ex_index().unwrap()); /// Extensions to [`SslContextBuilder`]. /// @@ -270,7 +272,7 @@ fn with_private_key_method( /// created by `create_fut` returns `Poll::Ready(_)` on the first poll call. fn with_ex_data_future( ssl_handle: &mut H, - index: Index>>, + index: Index>>>, get_ssl_mut: impl Fn(&mut H) -> &mut ssl::SslRef, create_fut: impl FnOnce(&mut H) -> Result, E>, into_result: impl Fn(R) -> Result, @@ -284,7 +286,7 @@ fn with_ex_data_future( let mut ctx = Context::from_waker(&waker); - if let Some(data @ Some(_)) = ssl.ex_data_mut(index) { + if let Some(data @ Some(_)) = ssl.ex_data_mut(index).map(MutOnly::get_mut) { let fut_result = into_result(ready!(data.as_mut().unwrap().as_mut().poll(&mut ctx))); *data = None; @@ -296,7 +298,7 @@ fn with_ex_data_future( match fut.as_mut().poll(&mut ctx) { Poll::Ready(fut_result) => Poll::Ready(into_result(fut_result)), Poll::Pending => { - get_ssl_mut(ssl_handle).set_ex_data(index, Some(fut)); + get_ssl_mut(ssl_handle).set_ex_data(index, MutOnly::new(Some(fut))); Poll::Pending } diff --git a/tokio-boring/src/lib.rs b/tokio-boring/src/lib.rs index a3c4eae2..adf4a63a 100644 --- a/tokio-boring/src/lib.rs +++ b/tokio-boring/src/lib.rs @@ -29,6 +29,7 @@ use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; mod async_callbacks; mod bridge; +mod mut_only; use self::async_callbacks::TASK_WAKER_INDEX; pub use self::async_callbacks::{ diff --git a/tokio-boring/src/mut_only.rs b/tokio-boring/src/mut_only.rs new file mode 100644 index 00000000..219706c0 --- /dev/null +++ b/tokio-boring/src/mut_only.rs @@ -0,0 +1,14 @@ +pub(crate) struct MutOnly(T); + +impl MutOnly { + pub(crate) fn new(value: T) -> Self { + Self(value) + } + + pub(crate) fn get_mut(&mut self) -> &mut T { + &mut self.0 + } +} + +/// SAFETY: The type does not let anyone get a &T so Sync is irrelevant. +unsafe impl Sync for MutOnly {}