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:
1 parent
20d146d9bd
commit
baf5a95cae
19 files changed
+905
-250
No files matched your search
@@ -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"))]
|
||||
|
||||
Reference in new issue
Block a user