better join

This commit is contained in:
nora 2024-06-27 19:48:25 +02:00
parent 8c59c7b3ae
commit bfa81495b1
2 changed files with 7 additions and 2 deletions

View file

@ -34,10 +34,15 @@ impl<F1: Future, F2: Future> Future for Join2<F1, F2> {
type Output = (F1::Output, F2::Output); type Output = (F1::Output, F2::Output);
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
// SAFETY: We must never move out of `this`.
// We do indeed not do this, except we do, when the future complets.
// This is okay, as we do this after dropping it.
// We also never expose a `&mut` to anyone.
let this = unsafe { self.get_unchecked_mut() }; let this = unsafe { self.get_unchecked_mut() };
fn make_progress<F: Future>(field: &mut JoinState<F>, cx: &mut Context<'_>) { fn make_progress<F: Future>(field: &mut JoinState<F>, cx: &mut Context<'_>) {
match field { match field {
// SAFETY: This is just projecting the pin into the field.
JoinState::Pending(fut) => match unsafe { Pin::new_unchecked(fut) }.poll(cx) { JoinState::Pending(fut) => match unsafe { Pin::new_unchecked(fut) }.poll(cx) {
Poll::Ready(result) => { Poll::Ready(result) => {
*field = JoinState::Ready(result); *field = JoinState::Ready(result);

View file

@ -1,7 +1,7 @@
mod executor; mod executor;
mod spawn_blocking; mod spawn_blocking;
mod join; mod join2;
pub use executor::*; pub use executor::*;
pub use spawn_blocking::*; pub use spawn_blocking::*;
pub use join::*; pub use join2::*;