diff --git a/gpui/src/app.rs b/gpui/src/app.rs index f62ab3f6be..33899fc77a 100644 --- a/gpui/src/app.rs +++ b/gpui/src/app.rs @@ -2059,7 +2059,7 @@ pub enum EntityLocation { pub struct ModelHandle { model_id: usize, model_type: PhantomData, - ref_counts: Weak>, + ref_counts: Arc>, } impl ModelHandle { @@ -2068,7 +2068,7 @@ impl ModelHandle { Self { model_id, model_type: PhantomData, - ref_counts: Arc::downgrade(ref_counts), + ref_counts: ref_counts.clone(), } } @@ -2145,10 +2145,7 @@ impl ModelHandle { impl Clone for ModelHandle { fn clone(&self) -> Self { - if let Some(ref_counts) = self.ref_counts.upgrade() { - ref_counts.lock().inc_entity(self.model_id); - } - + self.ref_counts.lock().inc_entity(self.model_id); Self { model_id: self.model_id, model_type: PhantomData, @@ -2190,9 +2187,7 @@ unsafe impl Sync for ModelHandle {} impl Drop for ModelHandle { fn drop(&mut self) { - if let Some(ref_counts) = self.ref_counts.upgrade() { - ref_counts.lock().dec_model(self.model_id); - } + self.ref_counts.lock().dec_model(self.model_id); } } @@ -2239,14 +2234,12 @@ impl Clone for WeakModelHandle { pub struct AnyModelHandle { model_id: usize, - ref_counts: Weak>, + ref_counts: Arc>, } impl From> for AnyModelHandle { fn from(handle: ModelHandle) -> Self { - if let Some(ref_counts) = handle.ref_counts.upgrade() { - ref_counts.lock().inc_entity(handle.model_id); - } + handle.ref_counts.lock().inc_entity(handle.model_id); Self { model_id: handle.model_id, ref_counts: handle.ref_counts.clone(), @@ -2256,9 +2249,7 @@ impl From> for AnyModelHandle { impl Drop for AnyModelHandle { fn drop(&mut self) { - if let Some(ref_counts) = self.ref_counts.upgrade() { - ref_counts.lock().dec_model(self.model_id); - } + self.ref_counts.lock().dec_model(self.model_id); } } @@ -2266,7 +2257,7 @@ pub struct ViewHandle { window_id: usize, view_id: usize, view_type: PhantomData, - ref_counts: Weak>, + ref_counts: Arc>, } impl ViewHandle { @@ -2276,7 +2267,7 @@ impl ViewHandle { window_id, view_id, view_type: PhantomData, - ref_counts: Arc::downgrade(ref_counts), + ref_counts: ref_counts.clone(), } } @@ -2353,10 +2344,7 @@ impl ViewHandle { impl Clone for ViewHandle { fn clone(&self) -> Self { - if let Some(ref_counts) = self.ref_counts.upgrade() { - ref_counts.lock().inc_entity(self.view_id); - } - + self.ref_counts.lock().inc_entity(self.view_id); Self { window_id: self.window_id, view_id: self.view_id, @@ -2385,9 +2373,9 @@ impl Debug for ViewHandle { impl Drop for ViewHandle { fn drop(&mut self) { - if let Some(ref_counts) = self.ref_counts.upgrade() { - ref_counts.lock().dec_view(self.window_id, self.view_id); - } + self.ref_counts + .lock() + .dec_view(self.window_id, self.view_id); } } @@ -2406,7 +2394,7 @@ pub struct AnyViewHandle { window_id: usize, view_id: usize, view_type: TypeId, - ref_counts: Weak>, + ref_counts: Arc>, } impl AnyViewHandle { @@ -2420,19 +2408,26 @@ impl AnyViewHandle { pub fn downcast(self) -> Option> { if self.is::() { - if let Some(ref_counts) = self.ref_counts.upgrade() { - return Some(ViewHandle::new(self.window_id, self.view_id, &ref_counts)); + let result = Some(ViewHandle { + window_id: self.window_id, + view_id: self.view_id, + ref_counts: self.ref_counts.clone(), + view_type: PhantomData, + }); + unsafe { + Arc::decrement_strong_count(&self.ref_counts); } + std::mem::forget(self); + result + } else { + None } - None } } impl From<&ViewHandle> for AnyViewHandle { fn from(handle: &ViewHandle) -> Self { - if let Some(ref_counts) = handle.ref_counts.upgrade() { - ref_counts.lock().inc_entity(handle.view_id); - } + handle.ref_counts.lock().inc_entity(handle.view_id); AnyViewHandle { window_id: handle.window_id, view_id: handle.view_id, @@ -2444,15 +2439,25 @@ impl From<&ViewHandle> for AnyViewHandle { impl From> for AnyViewHandle { fn from(handle: ViewHandle) -> Self { - (&handle).into() + let any_handle = AnyViewHandle { + window_id: handle.window_id, + view_id: handle.view_id, + view_type: TypeId::of::(), + ref_counts: handle.ref_counts.clone(), + }; + unsafe { + Arc::decrement_strong_count(&handle.ref_counts); + } + std::mem::forget(handle); + any_handle } } impl Drop for AnyViewHandle { fn drop(&mut self) { - if let Some(ref_counts) = self.ref_counts.upgrade() { - ref_counts.lock().dec_view(self.window_id, self.view_id); - } + self.ref_counts + .lock() + .dec_view(self.window_id, self.view_id); } } @@ -2473,7 +2478,7 @@ impl WeakViewHandle { pub fn upgrade(&self, ctx: impl AsRef) -> Option> { let ctx = ctx.as_ref(); - if ctx.views.get(&(self.window_id, self.view_id)).is_some() { + if ctx.ref_counts.lock().is_entity_alive(self.view_id) { Some(ViewHandle::new( self.window_id, self.view_id, @@ -2552,8 +2557,8 @@ struct RefCounts { } impl RefCounts { - fn inc_entity(&mut self, model_id: usize) { - *self.entity_counts.entry(model_id).or_insert(0) += 1; + fn inc_entity(&mut self, entity_id: usize) { + *self.entity_counts.entry(entity_id).or_insert(0) += 1; } fn inc_value(&mut self, tag_type_id: TypeId, id: usize) { @@ -2588,6 +2593,10 @@ impl RefCounts { } } + fn is_entity_alive(&self, entity_id: usize) -> bool { + self.entity_counts.contains_key(&entity_id) + } + fn take_dropped( &mut self, ) -> (