use {
crate::sync::{EntryData, SyncWeakList, SyncWeakListElement},
alloc::sync::{Arc, Weak},
core::{
fmt::{Debug, Formatter},
mem,
},
parking_lot::Mutex,
};
impl<T> SyncWeakListElement<T>
where
T: ?Sized,
{
pub fn new(t: Weak<T>) -> Self {
Self {
t,
data: Mutex::new(EntryData {
id: 0,
owner: Default::default(),
}),
}
}
pub fn attach(&self, to: &SyncWeakList<T>) {
self.detach();
let data = &mut *self.data.lock();
data.owner = Arc::downgrade(&to.data);
let list_data = &mut *to.data.lock();
data.id = list_data.next_id;
list_data.next_id += 1;
list_data.members.insert(data.id, self.t.clone());
}
pub fn detach(&self) {
let data = &mut *self.data.lock();
let prev = mem::take(&mut data.owner).upgrade();
if let Some(prev) = prev {
let list_data = &mut *prev.lock();
list_data.members.remove(&data.id);
}
}
}
impl<T> Drop for SyncWeakListElement<T>
where
T: ?Sized,
{
fn drop(&mut self) {
self.detach();
}
}
impl<T> Debug for SyncWeakListElement<T>
where
T: ?Sized,
{
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
let data = self.data.lock();
let owner = data.owner.upgrade();
let owner_id = owner.as_ref().map(Arc::as_ptr);
f.debug_struct("SyncWeakListElement")
.field("list", &owner_id)
.finish_non_exhaustive()
}
}