fix signals crate
This commit is contained in:
1 parent
9e388c3c51
commit
6b17d3db1e
11 files changed
+277
-129
No files matched your search
@@ -1,10 +1,7 @@
|
||||
#![doc = include_str!("../README.md")]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
use error::*;
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use references::{GenerationalRefBorrowInfo, GenerationalRefMutBorrowInfo};
|
||||
use std::any::Any;
|
||||
use parking_lot::Mutex;
|
||||
use std::sync::atomic::AtomicU32;
|
||||
use std::{
|
||||
fmt::Debug,
|
||||
@@ -13,7 +10,10 @@ use std::{
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use unsync::UnsyncStorage;
|
||||
pub use error::*;
|
||||
pub use references::*;
|
||||
pub use sync::SyncStorage;
|
||||
pub use unsync::UnsyncStorage;
|
||||
|
||||
mod error;
|
||||
mod references;
|
||||
@@ -37,12 +37,12 @@ fn reused() {
|
||||
let first_ptr;
|
||||
{
|
||||
let owner = UnsyncStorage::owner();
|
||||
first_ptr = owner.insert(1).raw.data.data_ptr();
|
||||
first_ptr = owner.insert(1).raw.0.data.data_ptr();
|
||||
drop(owner);
|
||||
}
|
||||
{
|
||||
let owner = UnsyncStorage::owner();
|
||||
let second_ptr = owner.insert(1234).raw.data.data_ptr();
|
||||
let second_ptr = owner.insert(1234).raw.0.data.data_ptr();
|
||||
assert_eq!(first_ptr, second_ptr);
|
||||
drop(owner);
|
||||
}
|
||||
@@ -233,7 +233,7 @@ impl<T: 'static, S: Storage<T>> GenerationalBox<T, S> {
|
||||
created_at: self.created_at,
|
||||
}));
|
||||
}
|
||||
self.raw.0.data.try_read(
|
||||
let result = self.raw.0.data.try_read(
|
||||
#[cfg(any(debug_assertions, feature = "debug_ownership"))]
|
||||
self.created_at,
|
||||
#[cfg(any(debug_assertions, feature = "debug_ownership"))]
|
||||
@@ -241,7 +241,18 @@ impl<T: 'static, S: Storage<T>> GenerationalBox<T, S> {
|
||||
borrowed_at: std::panic::Location::caller(),
|
||||
borrowed_from: &self.raw.0.borrow,
|
||||
},
|
||||
)
|
||||
);
|
||||
|
||||
if result.is_ok() {
|
||||
self.raw
|
||||
.0
|
||||
.borrow
|
||||
.borrowed_at
|
||||
.write()
|
||||
.push(std::panic::Location::caller());
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
/// Read the value. Panics if the value is no longer valid.
|
||||
@@ -259,14 +270,20 @@ impl<T: 'static, S: Storage<T>> GenerationalBox<T, S> {
|
||||
created_at: self.created_at,
|
||||
}));
|
||||
}
|
||||
self.raw.0.data.try_write(
|
||||
let result = self.raw.0.data.try_write(
|
||||
#[cfg(any(debug_assertions, feature = "debug_ownership"))]
|
||||
self.created_at,
|
||||
#[cfg(any(debug_assertions, feature = "debug_ownership"))]
|
||||
GenerationalRefMutBorrowInfo {
|
||||
borrowed_from: &self.raw.0.borrow,
|
||||
},
|
||||
)
|
||||
);
|
||||
|
||||
if result.is_ok() {
|
||||
*self.raw.0.borrow.borrowed_mut_at.write() = Some(std::panic::Location::caller());
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
/// Write the value. Panics if the value is no longer valid.
|
||||
@@ -296,9 +313,9 @@ impl<T: 'static, S: Storage<T>> GenerationalBox<T, S> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, S: 'static + Copy> Copy for GenerationalBox<T, S> {}
|
||||
impl<T, S: 'static> Copy for GenerationalBox<T, S> {}
|
||||
|
||||
impl<T, S: Copy> Clone for GenerationalBox<T, S> {
|
||||
impl<T, S> Clone for GenerationalBox<T, S> {
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
@@ -384,7 +401,8 @@ pub trait AnyStorage: Default {
|
||||
}
|
||||
}
|
||||
|
||||
struct MemoryLocation<S: 'static = UnsyncStorage>(&'static MemoryLocationInner<S>);
|
||||
/// A dynamic memory location that can be used in a generational box.
|
||||
pub struct MemoryLocation<S: 'static = UnsyncStorage>(&'static MemoryLocationInner<S>);
|
||||
|
||||
impl<S: 'static> Clone for MemoryLocation<S> {
|
||||
fn clone(&self) -> Self {
|
||||
@@ -397,8 +415,31 @@ impl<S: 'static> Copy for MemoryLocation<S> {}
|
||||
#[cfg(any(debug_assertions, feature = "debug_borrows"))]
|
||||
#[derive(Debug, Default)]
|
||||
struct MemoryLocationBorrowInfo {
|
||||
borrowed_at: RwLock<Vec<&'static std::panic::Location<'static>>>,
|
||||
borrowed_mut_at: RwLock<Option<&'static std::panic::Location<'static>>>,
|
||||
pub(crate) borrowed_at: parking_lot::RwLock<Vec<&'static std::panic::Location<'static>>>,
|
||||
pub(crate) borrowed_mut_at: parking_lot::RwLock<Option<&'static std::panic::Location<'static>>>,
|
||||
}
|
||||
|
||||
impl MemoryLocationBorrowInfo {
|
||||
fn borrow_mut_error(&self) -> BorrowMutError {
|
||||
if let Some(borrowed_mut_at) = self.borrowed_mut_at.read().as_ref() {
|
||||
BorrowMutError::AlreadyBorrowedMut(crate::error::AlreadyBorrowedMutError {
|
||||
#[cfg(any(debug_assertions, feature = "debug_borrows"))]
|
||||
borrowed_mut_at,
|
||||
})
|
||||
} else {
|
||||
BorrowMutError::AlreadyBorrowed(crate::error::AlreadyBorrowedError {
|
||||
#[cfg(any(debug_assertions, feature = "debug_borrows"))]
|
||||
borrowed_at: self.borrowed_at.read().clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn borrow_error(&self) -> BorrowError {
|
||||
BorrowError::AlreadyBorrowedMut(crate::error::AlreadyBorrowedMutError {
|
||||
#[cfg(any(debug_assertions, feature = "debug_ownership"))]
|
||||
borrowed_mut_at: self.borrowed_mut_at.read().unwrap(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
struct MemoryLocationInner<S = UnsyncStorage> {
|
||||
@@ -444,65 +485,6 @@ impl<S> MemoryLocation<S> {
|
||||
_marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn try_borrow<T: Any>(
|
||||
&self,
|
||||
#[cfg(any(debug_assertions, feature = "debug_ownership"))]
|
||||
created_at: &'static std::panic::Location<'static>,
|
||||
) -> std::result::Result<<S as Storage<T>>::Ref, error::BorrowError>
|
||||
where
|
||||
S: Storage<T>,
|
||||
{
|
||||
match self.0.data.try_read(
|
||||
#[cfg(any(debug_assertions, feature = "debug_ownership"))]
|
||||
created_at,
|
||||
#[cfg(any(debug_assertions, feature = "debug_ownership"))]
|
||||
GenerationalRefBorrowInfo {
|
||||
borrowed_at: std::panic::Location::caller(),
|
||||
borrowed_from: &self.0.borrow,
|
||||
},
|
||||
) {
|
||||
Ok(read) => {
|
||||
#[cfg(any(debug_assertions, feature = "debug_borrows"))]
|
||||
self.0
|
||||
.borrow
|
||||
.borrowed_at
|
||||
.write()
|
||||
.push(std::panic::Location::caller());
|
||||
Ok(read)
|
||||
}
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn try_borrow_mut<T: Any>(
|
||||
&self,
|
||||
#[cfg(any(debug_assertions, feature = "debug_ownership"))]
|
||||
created_at: &'static std::panic::Location<'static>,
|
||||
) -> std::result::Result<<S as Storage<T>>::Mut, error::BorrowMutError>
|
||||
where
|
||||
S: Storage<T>,
|
||||
{
|
||||
match self.0.data.try_write(
|
||||
#[cfg(any(debug_assertions, feature = "debug_ownership"))]
|
||||
created_at,
|
||||
#[cfg(any(debug_assertions, feature = "debug_ownership"))]
|
||||
GenerationalRefMutBorrowInfo {
|
||||
borrowed_from: &self.0.borrow,
|
||||
},
|
||||
) {
|
||||
Ok(read) => {
|
||||
#[cfg(any(debug_assertions, feature = "debug_borrows"))]
|
||||
{
|
||||
*self.0.borrow.borrowed_mut_at.write() = Some(std::panic::Location::caller());
|
||||
}
|
||||
Ok(read)
|
||||
}
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Owner: Handles dropping generational boxes. The owner acts like a runtime lifetime guard. Any states that you create with an owner will be dropped when that owner is dropped.
|
||||
@@ -511,7 +493,20 @@ pub struct Owner<S: AnyStorage + 'static = UnsyncStorage> {
|
||||
phantom: PhantomData<S>,
|
||||
}
|
||||
|
||||
impl<S: AnyStorage + Copy> Owner<S> {
|
||||
impl<S: AnyStorage> Owner<S> {
|
||||
/// Insert a value into the store. The value will be dropped when the owner is dropped.
|
||||
#[track_caller]
|
||||
pub fn insert<T: 'static>(&self, value: T) -> GenerationalBox<T, S>
|
||||
where
|
||||
S: Storage<T>,
|
||||
{
|
||||
self.insert_with_caller(
|
||||
value,
|
||||
#[cfg(any(debug_assertions, feature = "debug_ownership"))]
|
||||
std::panic::Location::caller(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Insert a value into the store with a specific location blamed for creating the value. The value will be dropped when the owner is dropped.
|
||||
pub fn insert_with_caller<T: 'static>(
|
||||
&self,
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::{
|
||||
ops::{Deref, DerefMut},
|
||||
};
|
||||
|
||||
use crate::{Mappable, MappableMut, MemoryLocationBorrowInfo};
|
||||
use crate::{Mappable, MappableMut};
|
||||
|
||||
/// A reference to a value in a generational box.
|
||||
pub struct GenerationalRef<T: 'static, R: Mappable<T>> {
|
||||
@@ -73,9 +73,10 @@ impl<T: 'static, R: Mappable<T>> Deref for GenerationalRef<T, R> {
|
||||
}
|
||||
|
||||
#[cfg(any(debug_assertions, feature = "debug_borrows"))]
|
||||
pub(crate) struct GenerationalRefBorrowInfo {
|
||||
/// Information about a borrow.
|
||||
pub struct GenerationalRefBorrowInfo {
|
||||
pub(crate) borrowed_at: &'static std::panic::Location<'static>,
|
||||
pub(crate) borrowed_from: &'static MemoryLocationBorrowInfo,
|
||||
pub(crate) borrowed_from: &'static crate::MemoryLocationBorrowInfo,
|
||||
}
|
||||
|
||||
#[cfg(any(debug_assertions, feature = "debug_borrows"))]
|
||||
@@ -157,8 +158,10 @@ impl<T: 'static, W: MappableMut<T>> DerefMut for GenerationalRefMut<T, W> {
|
||||
}
|
||||
|
||||
#[cfg(any(debug_assertions, feature = "debug_borrows"))]
|
||||
pub(crate) struct GenerationalRefMutBorrowInfo {
|
||||
pub(crate) borrowed_from: &'static MemoryLocationBorrowInfo,
|
||||
/// Information about a mutable borrow.
|
||||
pub struct GenerationalRefMutBorrowInfo {
|
||||
/// The location where the borrow occurred.
|
||||
pub(crate) borrowed_from: &'static crate::MemoryLocationBorrowInfo,
|
||||
}
|
||||
|
||||
#[cfg(any(debug_assertions, feature = "debug_borrows"))]
|
||||
|
||||
@@ -5,10 +5,7 @@ use std::sync::{Arc, OnceLock};
|
||||
|
||||
use crate::{
|
||||
error::{self, ValueDroppedError},
|
||||
references::{
|
||||
GenerationalRef, GenerationalRefBorrowInfo, GenerationalRefMut,
|
||||
GenerationalRefMutBorrowInfo,
|
||||
},
|
||||
references::{GenerationalRef, GenerationalRefMut},
|
||||
AnyStorage, Mappable, MappableMut, MemoryLocation, MemoryLocationInner, Storage,
|
||||
};
|
||||
|
||||
@@ -89,9 +86,14 @@ impl<T: Sync + Send + 'static> Storage<T> for SyncStorage {
|
||||
&'static self,
|
||||
#[cfg(any(debug_assertions, feature = "debug_ownership"))]
|
||||
created_at: &'static std::panic::Location<'static>,
|
||||
#[cfg(any(debug_assertions, feature = "debug_ownership"))] at: GenerationalRefBorrowInfo,
|
||||
#[cfg(any(debug_assertions, feature = "debug_ownership"))]
|
||||
at: crate::GenerationalRefBorrowInfo,
|
||||
) -> Result<Self::Ref, error::BorrowError> {
|
||||
RwLockReadGuard::try_map(self.0.read(), |any| any.as_ref()?.downcast_ref())
|
||||
let read = self
|
||||
.0
|
||||
.try_read()
|
||||
.ok_or_else(|| at.borrowed_from.borrow_error())?;
|
||||
RwLockReadGuard::try_map(read, |any| any.as_ref()?.downcast_ref())
|
||||
.map_err(|_| {
|
||||
error::BorrowError::Dropped(ValueDroppedError {
|
||||
#[cfg(any(debug_assertions, feature = "debug_ownership"))]
|
||||
@@ -111,9 +113,14 @@ impl<T: Sync + Send + 'static> Storage<T> for SyncStorage {
|
||||
&'static self,
|
||||
#[cfg(any(debug_assertions, feature = "debug_ownership"))]
|
||||
created_at: &'static std::panic::Location<'static>,
|
||||
#[cfg(any(debug_assertions, feature = "debug_ownership"))] at: GenerationalRefMutBorrowInfo,
|
||||
#[cfg(any(debug_assertions, feature = "debug_ownership"))]
|
||||
at: crate::GenerationalRefMutBorrowInfo,
|
||||
) -> Result<Self::Mut, error::BorrowMutError> {
|
||||
RwLockWriteGuard::try_map(self.0.write(), |any| any.as_mut()?.downcast_mut())
|
||||
let write = self
|
||||
.0
|
||||
.try_write()
|
||||
.ok_or_else(|| at.borrowed_from.borrow_mut_error())?;
|
||||
RwLockWriteGuard::try_map(write, |any| any.as_mut()?.downcast_mut())
|
||||
.map_err(|_| {
|
||||
error::BorrowMutError::Dropped(ValueDroppedError {
|
||||
#[cfg(any(debug_assertions, feature = "debug_ownership"))]
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
use crate::{
|
||||
references::{
|
||||
GenerationalRef, GenerationalRefBorrowInfo, GenerationalRefMut,
|
||||
GenerationalRefMutBorrowInfo,
|
||||
},
|
||||
references::{GenerationalRef, GenerationalRefMut},
|
||||
AnyStorage, Mappable, MappableMut, MemoryLocation, MemoryLocationInner, Storage,
|
||||
};
|
||||
use std::cell::{Ref, RefCell, RefMut};
|
||||
@@ -54,14 +51,19 @@ impl<T: 'static> Storage<T> for UnsyncStorage {
|
||||
&'static self,
|
||||
#[cfg(any(debug_assertions, feature = "debug_ownership"))]
|
||||
created_at: &'static std::panic::Location<'static>,
|
||||
#[cfg(any(debug_assertions, feature = "debug_ownership"))] at: GenerationalRefBorrowInfo,
|
||||
#[cfg(any(debug_assertions, feature = "debug_ownership"))]
|
||||
at: crate::GenerationalRefBorrowInfo,
|
||||
) -> Result<Self::Ref, crate::error::BorrowError> {
|
||||
Ref::filter_map(self.0.borrow(), |any| any.as_ref()?.downcast_ref())
|
||||
let borrow = self
|
||||
.0
|
||||
.try_borrow()
|
||||
.map_err(|_| at.borrowed_from.borrow_error())?;
|
||||
Ref::filter_map(borrow, |any| any.as_ref()?.downcast_ref())
|
||||
.map_err(|_| {
|
||||
crate::error::BorrowError::Dropped(
|
||||
crate::error::BorrowError::Dropped(crate::error::ValueDroppedError {
|
||||
#[cfg(any(debug_assertions, feature = "debug_ownership"))]
|
||||
crate::error::ValueDroppedError { created_at },
|
||||
)
|
||||
created_at,
|
||||
})
|
||||
})
|
||||
.map(|guard| {
|
||||
GenerationalRef::new(
|
||||
@@ -76,14 +78,19 @@ impl<T: 'static> Storage<T> for UnsyncStorage {
|
||||
&'static self,
|
||||
#[cfg(any(debug_assertions, feature = "debug_ownership"))]
|
||||
created_at: &'static std::panic::Location<'static>,
|
||||
#[cfg(any(debug_assertions, feature = "debug_ownership"))] at: GenerationalRefMutBorrowInfo,
|
||||
#[cfg(any(debug_assertions, feature = "debug_ownership"))]
|
||||
at: crate::GenerationalRefMutBorrowInfo,
|
||||
) -> Result<Self::Mut, crate::error::BorrowMutError> {
|
||||
RefMut::filter_map(self.0.borrow_mut(), |any| any.as_mut()?.downcast_mut())
|
||||
let borrow = self
|
||||
.0
|
||||
.try_borrow_mut()
|
||||
.map_err(|_| at.borrowed_from.borrow_mut_error())?;
|
||||
RefMut::filter_map(borrow, |any| any.as_mut()?.downcast_mut())
|
||||
.map_err(|_| {
|
||||
crate::error::BorrowMutError::Dropped(
|
||||
crate::error::BorrowMutError::Dropped(crate::error::ValueDroppedError {
|
||||
#[cfg(any(debug_assertions, feature = "debug_ownership"))]
|
||||
crate::error::ValueDroppedError { created_at },
|
||||
)
|
||||
created_at,
|
||||
})
|
||||
})
|
||||
.map(|guard| {
|
||||
GenerationalRefMut::new(
|
||||
|
||||
Reference in new issue
Block a user