mirror of
https://github.com/leptos-rs/leptos
synced 2024-11-10 06:44:17 +00:00
fix: remove Owner from thread-local when it is ordinarily dropped, to ensure cleanup (closes #2942) (#2944)
This commit is contained in:
parent
4a76aead68
commit
57bd343f4a
3 changed files with 18 additions and 1 deletions
|
@ -59,7 +59,7 @@ pub trait ExtendResponse: Sized {
|
||||||
// drop the owner, cleaning up the reactive runtime,
|
// drop the owner, cleaning up the reactive runtime,
|
||||||
// once the stream is over
|
// once the stream is over
|
||||||
.chain(once(async move {
|
.chain(once(async move {
|
||||||
drop(owner);
|
owner.unset();
|
||||||
Default::default()
|
Default::default()
|
||||||
})),
|
})),
|
||||||
));
|
));
|
||||||
|
|
|
@ -55,6 +55,12 @@ pub struct Owner {
|
||||||
pub(crate) shared_context: Option<Arc<dyn SharedContext + Send + Sync>>,
|
pub(crate) shared_context: Option<Arc<dyn SharedContext + Send + Sync>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialEq for Owner {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
Arc::ptr_eq(&self.inner, &other.inner)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
thread_local! {
|
thread_local! {
|
||||||
static OWNER: RefCell<Option<Owner>> = Default::default();
|
static OWNER: RefCell<Option<Owner>> = Default::default();
|
||||||
}
|
}
|
||||||
|
@ -241,6 +247,15 @@ impl Owner {
|
||||||
self.shared_context.clone()
|
self.shared_context.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Removes this from its state as the thread-local owner and drops it.
|
||||||
|
pub fn unset(self) {
|
||||||
|
OWNER.with_borrow_mut(|owner| {
|
||||||
|
if owner.as_ref() == Some(&self) {
|
||||||
|
mem::take(owner);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the current [`SharedContext`], if any.
|
/// Returns the current [`SharedContext`], if any.
|
||||||
#[cfg(feature = "hydration")]
|
#[cfg(feature = "hydration")]
|
||||||
pub fn current_shared_context(
|
pub fn current_shared_context(
|
||||||
|
|
|
@ -313,6 +313,7 @@ impl<T, S: Storage<T>> StoredValue<T, S> {
|
||||||
/// assert_eq!(last, None);
|
/// assert_eq!(last, None);
|
||||||
/// assert_eq!(length_fn(), None);
|
/// assert_eq!(length_fn(), None);
|
||||||
/// ```
|
/// ```
|
||||||
|
#[track_caller]
|
||||||
pub fn try_with_value<U>(&self, fun: impl FnOnce(&T) -> U) -> Option<U> {
|
pub fn try_with_value<U>(&self, fun: impl FnOnce(&T) -> U) -> Option<U> {
|
||||||
S::try_with(self.node, fun)
|
S::try_with(self.node, fun)
|
||||||
}
|
}
|
||||||
|
@ -347,6 +348,7 @@ impl<T, S: Storage<T>> StoredValue<T, S> {
|
||||||
/// assert_eq!(sum, 6);
|
/// assert_eq!(sum, 6);
|
||||||
/// assert_eq!(length_fn(), 3);
|
/// assert_eq!(length_fn(), 3);
|
||||||
/// ```
|
/// ```
|
||||||
|
#[track_caller]
|
||||||
pub fn with_value<U>(&self, fun: impl FnOnce(&T) -> U) -> U {
|
pub fn with_value<U>(&self, fun: impl FnOnce(&T) -> U) -> U {
|
||||||
self.try_with_value(fun)
|
self.try_with_value(fun)
|
||||||
.unwrap_or_else(unwrap_signal!(self))
|
.unwrap_or_else(unwrap_signal!(self))
|
||||||
|
|
Loading…
Reference in a new issue