From 8b936d8f1d92b0d6e0f934e8af27dbc2b7ddbd14 Mon Sep 17 00:00:00 2001 From: Filipe Rodrigues Date: Sun, 22 Dec 2024 18:28:42 +0000 Subject: [PATCH] Fixed `AsyncSignal` sometimes not triggering when values were loaded. --- dynatos-reactive/src/async_signal.rs | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/dynatos-reactive/src/async_signal.rs b/dynatos-reactive/src/async_signal.rs index b2c33a9..b46dae4 100644 --- a/dynatos-reactive/src/async_signal.rs +++ b/dynatos-reactive/src/async_signal.rs @@ -3,9 +3,6 @@ // TODO: Support wakers that wake from a separate thread // by using some runtime and a channel. -// TODO: Trigger whenever we finish loading the future, not just when -// the waker wakes. - // Imports #[cfg(not(feature = "sync"))] use std::thread::{self, ThreadId}; @@ -148,7 +145,9 @@ impl AsyncSignal { /// Inner function to try to load the future fn try_load(&self, cx: &mut task::Context<'_>) -> Option<&F::Output> { - self.inner + // Try to load the value + let value = self + .inner .value .get_or_try_init(|| { // Get the inner future through pin projection. @@ -171,7 +170,12 @@ impl AsyncSignal { Poll::Pending => Err(()), } }) - .ok() + .ok()?; + + // Once we have, trigger our trigger to ensure subscribers get woken + self.inner.waker.trigger.trigger(); + + Some(value) } /// Borrows the inner value, without polling the future. @@ -206,7 +210,7 @@ where F::Output: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let value = self.inner.value.get(); + let value = self.borrow_suspended(); f.debug_struct("AsyncSignal").field("value", &value).finish() } } @@ -219,11 +223,9 @@ impl SignalBorrow for AsyncSignal { #[track_caller] fn borrow(&self) -> Self::Ref<'_> { - self.inner.waker.trigger.gather_subscribers(); - - // If we're suspended, don't poll + // If we're suspended, borrow suspended if self.is_suspended() { - return self.inner.value.get(); + return self.borrow_suspended(); } // Otherwise, try to load it