Fix cloned rsx double drop (#2839)

* Implement Rc generational pointers

* Clean up error handling a bit

* start adding tests

* Simplify a few types

* Separate Rc and normal generational boxes

* Add tests for rc drop and read

* Move over the pointer instead of the data in ReadOnlySignal props

* Fix panic on ref drop and release mode builds

* final rc signal cleanup

* use rc generational boxes for event handlers as well

* add a regression test for read only signal cloning

* merge main

---------

Co-authored-by: Jonathan Kelley <jkelleyrtp@gmail.com>
This commit is contained in:
Evan AlmloffandJonathan Kelley authored and GitHub committed 2024-10-14 09:23:09 -07:00
1 parent 20d146d9bd
commit baf5a95cae
19 files changed
+905 -250

No files matched your search

+40 -10
View File
@@ -2,36 +2,66 @@ use crate::{
BorrowError, BorrowMutError, GenerationalLocation, GenerationalRefBorrowGuard,
GenerationalRefBorrowMutGuard,
};
use std::{
num::NonZeroU64,
sync::atomic::{AtomicU64, Ordering},
};
pub(crate) struct StorageEntry<T> {
generation: u64,
pub data: Option<T>,
pub(crate) struct RcStorageEntry<T> {
ref_count: AtomicU64,
pub data: T,
}
impl<T> Default for StorageEntry<T> {
fn default() -> Self {
impl<T> RcStorageEntry<T> {
pub const fn new(data: T) -> Self {
Self {
generation: 0,
data: None,
ref_count: AtomicU64::new(0),
data,
}
}
pub fn add_ref(&self) {
self.ref_count.fetch_add(1, Ordering::SeqCst);
}
pub fn drop_ref(&self) -> bool {
let new_ref_count = self.ref_count.fetch_sub(1, Ordering::SeqCst);
new_ref_count == 0
}
}
pub(crate) struct StorageEntry<T> {
generation: NonZeroU64,
pub(crate) data: T,
}
impl<T> StorageEntry<T> {
pub const fn new(data: T) -> Self {
Self {
generation: NonZeroU64::MIN,
data,
}
}
pub fn valid(&self, location: &GenerationalLocation) -> bool {
self.generation == location.generation
}
pub fn increment_generation(&mut self) {
self.generation += 1;
self.generation = self.generation.checked_add(1).unwrap();
}
pub fn generation(&self) -> u64 {
pub fn generation(&self) -> NonZeroU64 {
self.generation
}
}
impl<T: Default + 'static> Default for StorageEntry<T> {
fn default() -> Self {
Self::new(T::default())
}
}
#[derive(Default)]
pub(crate) struct MemoryLocationBorrowInfo(
#[cfg(any(debug_assertions, feature = "debug_borrows"))]