| 1 | use core::{ | 
| 2 | fmt, | 
|---|
| 3 | future::Future, | 
|---|
| 4 | marker::PhantomData, | 
|---|
| 5 | mem, | 
|---|
| 6 | pin::Pin, | 
|---|
| 7 | task::{Context, Poll}, | 
|---|
| 8 | }; | 
|---|
| 9 |  | 
|---|
| 10 | /// A custom trait object for polling futures, roughly akin to | 
|---|
| 11 | /// `Box<dyn Future<Output = T> + 'a>`. | 
|---|
| 12 | /// | 
|---|
| 13 | /// This custom trait object was introduced as currently it is not possible to | 
|---|
| 14 | /// take `dyn Trait` by value and `Box<dyn Trait>` is not available in no_std | 
|---|
| 15 | /// contexts. | 
|---|
| 16 | pub struct LocalFutureObj<'a, T> { | 
|---|
| 17 | future: *mut (dyn Future<Output = T> + 'static), | 
|---|
| 18 | drop_fn: unsafe fn(*mut (dyn Future<Output = T> + 'static)), | 
|---|
| 19 | _marker: PhantomData<&'a ()>, | 
|---|
| 20 | } | 
|---|
| 21 |  | 
|---|
| 22 | // As LocalFutureObj only holds pointers, even if we move it, the pointed to values won't move, | 
|---|
| 23 | // so this is safe as long as we don't provide any way for a user to directly access the pointers | 
|---|
| 24 | // and move their values. | 
|---|
| 25 | impl<T> Unpin for LocalFutureObj<'_, T> {} | 
|---|
| 26 |  | 
|---|
| 27 | #[ allow(single_use_lifetimes)] | 
|---|
| 28 | #[ allow(clippy::transmute_ptr_to_ptr)] | 
|---|
| 29 | unsafe fn remove_future_lifetime<'a, T>( | 
|---|
| 30 | ptr: *mut (dyn Future<Output = T> + 'a), | 
|---|
| 31 | ) -> *mut (dyn Future<Output = T> + 'static) { | 
|---|
| 32 | unsafe { mem::transmute(src:ptr) } | 
|---|
| 33 | } | 
|---|
| 34 |  | 
|---|
| 35 | #[ allow(single_use_lifetimes)] | 
|---|
| 36 | unsafe fn remove_drop_lifetime<'a, T>( | 
|---|
| 37 | ptr: unsafe fn(*mut (dyn Future<Output = T> + 'a)), | 
|---|
| 38 | ) -> unsafe fn(*mut (dyn Future<Output = T> + 'static)) { | 
|---|
| 39 | unsafe { mem::transmute(src:ptr) } | 
|---|
| 40 | } | 
|---|
| 41 |  | 
|---|
| 42 | impl<'a, T> LocalFutureObj<'a, T> { | 
|---|
| 43 | /// Create a `LocalFutureObj` from a custom trait object representation. | 
|---|
| 44 | #[ inline] | 
|---|
| 45 | pub fn new<F: UnsafeFutureObj<'a, T> + 'a>(f: F) -> Self { | 
|---|
| 46 | Self { | 
|---|
| 47 | future: unsafe { remove_future_lifetime(ptr:f.into_raw()) }, | 
|---|
| 48 | drop_fn: unsafe { remove_drop_lifetime(F::drop) }, | 
|---|
| 49 | _marker: PhantomData, | 
|---|
| 50 | } | 
|---|
| 51 | } | 
|---|
| 52 |  | 
|---|
| 53 | /// Converts the `LocalFutureObj` into a `FutureObj`. | 
|---|
| 54 | /// | 
|---|
| 55 | /// # Safety | 
|---|
| 56 | /// | 
|---|
| 57 | /// To make this operation safe one has to ensure that the `UnsafeFutureObj` | 
|---|
| 58 | /// instance from which this `LocalFutureObj` was created actually | 
|---|
| 59 | /// implements `Send`. | 
|---|
| 60 | #[ inline] | 
|---|
| 61 | pub unsafe fn into_future_obj(self) -> FutureObj<'a, T> { | 
|---|
| 62 | FutureObj(self) | 
|---|
| 63 | } | 
|---|
| 64 | } | 
|---|
| 65 |  | 
|---|
| 66 | impl<T> fmt::Debug for LocalFutureObj<'_, T> { | 
|---|
| 67 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | 
|---|
| 68 | f.debug_struct(name: "LocalFutureObj").finish() | 
|---|
| 69 | } | 
|---|
| 70 | } | 
|---|
| 71 |  | 
|---|
| 72 | impl<'a, T> From<FutureObj<'a, T>> for LocalFutureObj<'a, T> { | 
|---|
| 73 | #[ inline] | 
|---|
| 74 | fn from(f: FutureObj<'a, T>) -> Self { | 
|---|
| 75 | f.0 | 
|---|
| 76 | } | 
|---|
| 77 | } | 
|---|
| 78 |  | 
|---|
| 79 | impl<T> Future for LocalFutureObj<'_, T> { | 
|---|
| 80 | type Output = T; | 
|---|
| 81 |  | 
|---|
| 82 | #[ inline] | 
|---|
| 83 | fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> { | 
|---|
| 84 | unsafe { Pin::new_unchecked(&mut *self.future).poll(cx) } | 
|---|
| 85 | } | 
|---|
| 86 | } | 
|---|
| 87 |  | 
|---|
| 88 | impl<T> Drop for LocalFutureObj<'_, T> { | 
|---|
| 89 | fn drop(&mut self) { | 
|---|
| 90 | unsafe { (self.drop_fn)(self.future) } | 
|---|
| 91 | } | 
|---|
| 92 | } | 
|---|
| 93 |  | 
|---|
| 94 | /// A custom trait object for polling futures, roughly akin to | 
|---|
| 95 | /// `Box<dyn Future<Output = T> + Send + 'a>`. | 
|---|
| 96 | /// | 
|---|
| 97 | /// This custom trait object was introduced as currently it is not possible to | 
|---|
| 98 | /// take `dyn Trait` by value and `Box<dyn Trait>` is not available in no_std | 
|---|
| 99 | /// contexts. | 
|---|
| 100 | /// | 
|---|
| 101 | /// You should generally not need to use this type outside of `no_std` or when | 
|---|
| 102 | /// implementing `Spawn`, consider using `BoxFuture` instead. | 
|---|
| 103 | pub struct FutureObj<'a, T>(LocalFutureObj<'a, T>); | 
|---|
| 104 |  | 
|---|
| 105 | impl<T> Unpin for FutureObj<'_, T> {} | 
|---|
| 106 | unsafe impl<T> Send for FutureObj<'_, T> {} | 
|---|
| 107 |  | 
|---|
| 108 | impl<'a, T> FutureObj<'a, T> { | 
|---|
| 109 | /// Create a `FutureObj` from a custom trait object representation. | 
|---|
| 110 | #[ inline] | 
|---|
| 111 | pub fn new<F: UnsafeFutureObj<'a, T> + Send>(f: F) -> Self { | 
|---|
| 112 | Self(LocalFutureObj::new(f)) | 
|---|
| 113 | } | 
|---|
| 114 | } | 
|---|
| 115 |  | 
|---|
| 116 | impl<T> fmt::Debug for FutureObj<'_, T> { | 
|---|
| 117 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | 
|---|
| 118 | f.debug_struct(name: "FutureObj").finish() | 
|---|
| 119 | } | 
|---|
| 120 | } | 
|---|
| 121 |  | 
|---|
| 122 | impl<T> Future for FutureObj<'_, T> { | 
|---|
| 123 | type Output = T; | 
|---|
| 124 |  | 
|---|
| 125 | #[ inline] | 
|---|
| 126 | fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> { | 
|---|
| 127 | Pin::new(&mut self.0).poll(cx) | 
|---|
| 128 | } | 
|---|
| 129 | } | 
|---|
| 130 |  | 
|---|
| 131 | /// A custom implementation of a future trait object for `FutureObj`, providing | 
|---|
| 132 | /// a vtable with drop support. | 
|---|
| 133 | /// | 
|---|
| 134 | /// This custom representation is typically used only in `no_std` contexts, | 
|---|
| 135 | /// where the default `Box`-based implementation is not available. | 
|---|
| 136 | /// | 
|---|
| 137 | /// # Safety | 
|---|
| 138 | /// | 
|---|
| 139 | /// See the safety notes on individual methods for what guarantees an | 
|---|
| 140 | /// implementor must provide. | 
|---|
| 141 | pub unsafe trait UnsafeFutureObj<'a, T>: 'a { | 
|---|
| 142 | /// Convert an owned instance into a (conceptually owned) fat pointer. | 
|---|
| 143 | /// | 
|---|
| 144 | /// # Safety | 
|---|
| 145 | /// | 
|---|
| 146 | /// ## Implementor | 
|---|
| 147 | /// | 
|---|
| 148 | /// The trait implementor must guarantee that it is safe to convert the | 
|---|
| 149 | /// provided `*mut (dyn Future<Output = T> + 'a)` into a `Pin<&mut (dyn | 
|---|
| 150 | /// Future<Output = T> + 'a)>` and call methods on it, non-reentrantly, | 
|---|
| 151 | /// until `UnsafeFutureObj::drop` is called with it. | 
|---|
| 152 | #[ allow(clippy::unnecessary_safety_doc)] | 
|---|
| 153 | fn into_raw(self) -> *mut (dyn Future<Output = T> + 'a); | 
|---|
| 154 |  | 
|---|
| 155 | /// Drops the future represented by the given fat pointer. | 
|---|
| 156 | /// | 
|---|
| 157 | /// # Safety | 
|---|
| 158 | /// | 
|---|
| 159 | /// ## Implementor | 
|---|
| 160 | /// | 
|---|
| 161 | /// The trait implementor must guarantee that it is safe to call this | 
|---|
| 162 | /// function once per `into_raw` invocation. | 
|---|
| 163 | /// | 
|---|
| 164 | /// ## Caller | 
|---|
| 165 | /// | 
|---|
| 166 | /// The caller must ensure: | 
|---|
| 167 | /// | 
|---|
| 168 | ///  * the pointer passed was obtained from an `into_raw` invocation from | 
|---|
| 169 | ///    this same trait object | 
|---|
| 170 | ///  * the pointer is not currently in use as a `Pin<&mut (dyn Future<Output | 
|---|
| 171 | ///    = T> + 'a)>` | 
|---|
| 172 | ///  * the pointer must not be used again after this function is called | 
|---|
| 173 | unsafe fn drop(ptr: *mut (dyn Future<Output = T> + 'a)); | 
|---|
| 174 | } | 
|---|
| 175 |  | 
|---|
| 176 | unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for &'a mut F | 
|---|
| 177 | where | 
|---|
| 178 | F: Future<Output = T> + Unpin + 'a, | 
|---|
| 179 | { | 
|---|
| 180 | fn into_raw(self) -> *mut (dyn Future<Output = T> + 'a) { | 
|---|
| 181 | self as *mut dyn Future<Output = T> | 
|---|
| 182 | } | 
|---|
| 183 |  | 
|---|
| 184 | unsafe fn drop(_ptr: *mut (dyn Future<Output = T> + 'a)) {} | 
|---|
| 185 | } | 
|---|
| 186 |  | 
|---|
| 187 | unsafe impl<'a, T> UnsafeFutureObj<'a, T> for &'a mut (dyn Future<Output = T> + Unpin + 'a) { | 
|---|
| 188 | fn into_raw(self) -> *mut (dyn Future<Output = T> + 'a) { | 
|---|
| 189 | self as *mut dyn Future<Output = T> | 
|---|
| 190 | } | 
|---|
| 191 |  | 
|---|
| 192 | unsafe fn drop(_ptr: *mut (dyn Future<Output = T> + 'a)) {} | 
|---|
| 193 | } | 
|---|
| 194 |  | 
|---|
| 195 | unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for Pin<&'a mut F> | 
|---|
| 196 | where | 
|---|
| 197 | F: Future<Output = T> + 'a, | 
|---|
| 198 | { | 
|---|
| 199 | fn into_raw(self) -> *mut (dyn Future<Output = T> + 'a) { | 
|---|
| 200 | unsafe { self.get_unchecked_mut() as *mut dyn Future<Output = T> } | 
|---|
| 201 | } | 
|---|
| 202 |  | 
|---|
| 203 | unsafe fn drop(_ptr: *mut (dyn Future<Output = T> + 'a)) {} | 
|---|
| 204 | } | 
|---|
| 205 |  | 
|---|
| 206 | unsafe impl<'a, T> UnsafeFutureObj<'a, T> for Pin<&'a mut (dyn Future<Output = T> + 'a)> { | 
|---|
| 207 | fn into_raw(self) -> *mut (dyn Future<Output = T> + 'a) { | 
|---|
| 208 | unsafe { self.get_unchecked_mut() as *mut dyn Future<Output = T> } | 
|---|
| 209 | } | 
|---|
| 210 |  | 
|---|
| 211 | unsafe fn drop(_ptr: *mut (dyn Future<Output = T> + 'a)) {} | 
|---|
| 212 | } | 
|---|
| 213 |  | 
|---|
| 214 | #[ cfg(feature = "alloc")] | 
|---|
| 215 | mod if_alloc { | 
|---|
| 216 | use super::*; | 
|---|
| 217 | use alloc::boxed::Box; | 
|---|
| 218 |  | 
|---|
| 219 | unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for Box<F> | 
|---|
| 220 | where | 
|---|
| 221 | F: Future<Output = T> + 'a, | 
|---|
| 222 | { | 
|---|
| 223 | fn into_raw(self) -> *mut (dyn Future<Output = T> + 'a) { | 
|---|
| 224 | Box::into_raw(self) | 
|---|
| 225 | } | 
|---|
| 226 |  | 
|---|
| 227 | unsafe fn drop(ptr: *mut (dyn Future<Output = T> + 'a)) { | 
|---|
| 228 | drop(unsafe { Box::from_raw(ptr.cast::<F>()) }) | 
|---|
| 229 | } | 
|---|
| 230 | } | 
|---|
| 231 |  | 
|---|
| 232 | unsafe impl<'a, T: 'a> UnsafeFutureObj<'a, T> for Box<dyn Future<Output = T> + 'a> { | 
|---|
| 233 | fn into_raw(self) -> *mut (dyn Future<Output = T> + 'a) { | 
|---|
| 234 | Box::into_raw(self) | 
|---|
| 235 | } | 
|---|
| 236 |  | 
|---|
| 237 | unsafe fn drop(ptr: *mut (dyn Future<Output = T> + 'a)) { | 
|---|
| 238 | drop(unsafe { Box::from_raw(ptr) }) | 
|---|
| 239 | } | 
|---|
| 240 | } | 
|---|
| 241 |  | 
|---|
| 242 | unsafe impl<'a, T: 'a> UnsafeFutureObj<'a, T> for Box<dyn Future<Output = T> + Send + 'a> { | 
|---|
| 243 | fn into_raw(self) -> *mut (dyn Future<Output = T> + 'a) { | 
|---|
| 244 | Box::into_raw(self) | 
|---|
| 245 | } | 
|---|
| 246 |  | 
|---|
| 247 | unsafe fn drop(ptr: *mut (dyn Future<Output = T> + 'a)) { | 
|---|
| 248 | drop(unsafe { Box::from_raw(ptr) }) | 
|---|
| 249 | } | 
|---|
| 250 | } | 
|---|
| 251 |  | 
|---|
| 252 | unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for Pin<Box<F>> | 
|---|
| 253 | where | 
|---|
| 254 | F: Future<Output = T> + 'a, | 
|---|
| 255 | { | 
|---|
| 256 | fn into_raw(self) -> *mut (dyn Future<Output = T> + 'a) { | 
|---|
| 257 | let mut this = mem::ManuallyDrop::new(self); | 
|---|
| 258 | unsafe { this.as_mut().get_unchecked_mut() as *mut _ } | 
|---|
| 259 | } | 
|---|
| 260 |  | 
|---|
| 261 | unsafe fn drop(ptr: *mut (dyn Future<Output = T> + 'a)) { | 
|---|
| 262 | drop(Pin::from(unsafe { Box::from_raw(ptr) })) | 
|---|
| 263 | } | 
|---|
| 264 | } | 
|---|
| 265 |  | 
|---|
| 266 | unsafe impl<'a, T: 'a> UnsafeFutureObj<'a, T> for Pin<Box<dyn Future<Output = T> + 'a>> { | 
|---|
| 267 | fn into_raw(self) -> *mut (dyn Future<Output = T> + 'a) { | 
|---|
| 268 | let mut this = mem::ManuallyDrop::new(self); | 
|---|
| 269 | unsafe { this.as_mut().get_unchecked_mut() as *mut _ } | 
|---|
| 270 | } | 
|---|
| 271 |  | 
|---|
| 272 | unsafe fn drop(ptr: *mut (dyn Future<Output = T> + 'a)) { | 
|---|
| 273 | drop(Pin::from(unsafe { Box::from_raw(ptr) })) | 
|---|
| 274 | } | 
|---|
| 275 | } | 
|---|
| 276 |  | 
|---|
| 277 | unsafe impl<'a, T: 'a> UnsafeFutureObj<'a, T> for Pin<Box<dyn Future<Output = T> + Send + 'a>> { | 
|---|
| 278 | fn into_raw(self) -> *mut (dyn Future<Output = T> + 'a) { | 
|---|
| 279 | let mut this = mem::ManuallyDrop::new(self); | 
|---|
| 280 | unsafe { this.as_mut().get_unchecked_mut() as *mut _ } | 
|---|
| 281 | } | 
|---|
| 282 |  | 
|---|
| 283 | unsafe fn drop(ptr: *mut (dyn Future<Output = T> + 'a)) { | 
|---|
| 284 | drop(Pin::from(unsafe { Box::from_raw(ptr) })) | 
|---|
| 285 | } | 
|---|
| 286 | } | 
|---|
| 287 |  | 
|---|
| 288 | impl<'a, F: Future<Output = ()> + Send + 'a> From<Box<F>> for FutureObj<'a, ()> { | 
|---|
| 289 | fn from(boxed: Box<F>) -> Self { | 
|---|
| 290 | Self::new(boxed) | 
|---|
| 291 | } | 
|---|
| 292 | } | 
|---|
| 293 |  | 
|---|
| 294 | impl<'a> From<Box<dyn Future<Output = ()> + Send + 'a>> for FutureObj<'a, ()> { | 
|---|
| 295 | fn from(boxed: Box<dyn Future<Output = ()> + Send + 'a>) -> Self { | 
|---|
| 296 | Self::new(boxed) | 
|---|
| 297 | } | 
|---|
| 298 | } | 
|---|
| 299 |  | 
|---|
| 300 | impl<'a, F: Future<Output = ()> + Send + 'a> From<Pin<Box<F>>> for FutureObj<'a, ()> { | 
|---|
| 301 | fn from(boxed: Pin<Box<F>>) -> Self { | 
|---|
| 302 | Self::new(boxed) | 
|---|
| 303 | } | 
|---|
| 304 | } | 
|---|
| 305 |  | 
|---|
| 306 | impl<'a> From<Pin<Box<dyn Future<Output = ()> + Send + 'a>>> for FutureObj<'a, ()> { | 
|---|
| 307 | fn from(boxed: Pin<Box<dyn Future<Output = ()> + Send + 'a>>) -> Self { | 
|---|
| 308 | Self::new(boxed) | 
|---|
| 309 | } | 
|---|
| 310 | } | 
|---|
| 311 |  | 
|---|
| 312 | impl<'a, F: Future<Output = ()> + 'a> From<Box<F>> for LocalFutureObj<'a, ()> { | 
|---|
| 313 | fn from(boxed: Box<F>) -> Self { | 
|---|
| 314 | Self::new(boxed) | 
|---|
| 315 | } | 
|---|
| 316 | } | 
|---|
| 317 |  | 
|---|
| 318 | impl<'a> From<Box<dyn Future<Output = ()> + 'a>> for LocalFutureObj<'a, ()> { | 
|---|
| 319 | fn from(boxed: Box<dyn Future<Output = ()> + 'a>) -> Self { | 
|---|
| 320 | Self::new(boxed) | 
|---|
| 321 | } | 
|---|
| 322 | } | 
|---|
| 323 |  | 
|---|
| 324 | impl<'a, F: Future<Output = ()> + 'a> From<Pin<Box<F>>> for LocalFutureObj<'a, ()> { | 
|---|
| 325 | fn from(boxed: Pin<Box<F>>) -> Self { | 
|---|
| 326 | Self::new(boxed) | 
|---|
| 327 | } | 
|---|
| 328 | } | 
|---|
| 329 |  | 
|---|
| 330 | impl<'a> From<Pin<Box<dyn Future<Output = ()> + 'a>>> for LocalFutureObj<'a, ()> { | 
|---|
| 331 | fn from(boxed: Pin<Box<dyn Future<Output = ()> + 'a>>) -> Self { | 
|---|
| 332 | Self::new(boxed) | 
|---|
| 333 | } | 
|---|
| 334 | } | 
|---|
| 335 | } | 
|---|
| 336 |  | 
|---|