diff --git a/litebox/src/fd/mod.rs b/litebox/src/fd/mod.rs index 6f988ce76..6114118c8 100644 --- a/litebox/src/fd/mod.rs +++ b/litebox/src/fd/mod.rs @@ -58,7 +58,8 @@ impl Descriptors { self.entries.push(None); self.entries.len() - 1 }); - let old = self.entries[idx].replace(IndividualEntry::new(Arc::new(RwLock::new(entry)))); + let old = + self.entries[idx].replace(IndividualEntry::new(SharedEntry::new::(entry))); assert!(old.is_none()); TypedFd { _phantom: PhantomData, @@ -118,7 +119,7 @@ impl Descriptors { }; fd.x.mark_as_closed(); Arc::into_inner(old.x) - .map(RwLock::into_inner) + .map(|shared| RwLock::into_inner(shared.entry)) .map(DescriptorEntry::into_subsystem_entry::) } @@ -142,10 +143,10 @@ impl Descriptors { }; if Arc::strong_count(&old.x) == 1 { // Unique, so we can just return it if allowed. - if can_close_immediately(old.x.read().as_subsystem::()) { + if can_close_immediately(old.x.entry.read().as_subsystem::()) { fd.x.mark_as_closed(); let entry = Arc::into_inner(old.x) - .map(RwLock::into_inner) + .map(|shared| RwLock::into_inner(shared.entry)) .map(DescriptorEntry::into_subsystem_entry::) .unwrap(); Some(CloseResult::Closed(entry)) @@ -189,7 +190,7 @@ impl Descriptors { // Each FD corresponds to an `IndividualEntry`, which has an Arc to a `DescriptorEntry`. If // we have the same number of FDs as matching to the strong-count of a descriptor entry, // then it must be the case that we have everything needed to close the entries out. - let removable_entries: Vec<*const RwLock<_, _>> = { + let removable_entries: Vec<*const SharedEntry> = { let mut strong_count_and_count = HashMap::<*const _, (usize, usize)>::new(); for fd in fds.iter() { let entry = &self.entries[fd.x.as_usize().unwrap()]; @@ -241,17 +242,17 @@ impl Descriptors { ) -> impl Iterator)> { self.entries.iter().enumerate().filter_map(|(i, entry)| { entry.as_ref().and_then(|e| { - let entry = e.read(); - if entry.matches_subsystem::() { - Some(( - InternalFd { - raw: i.try_into().unwrap(), - }, - crate::sync::RwLockReadGuard::map(entry, |e| e.as_subsystem::()), - )) - } else { - None + if !e.x.matches_subsystem::() { + return None; } + let entry = e.read(); + assert!(entry.matches_subsystem::()); + Some(( + InternalFd { + raw: i.try_into().unwrap(), + }, + crate::sync::RwLockReadGuard::map(entry, |e| e.as_subsystem::()), + )) }) }) } @@ -270,7 +271,7 @@ impl Descriptors { > { self.entries.iter().enumerate().filter_map(|(i, entry)| { entry.as_ref().and_then(|e| { - if !e.read().matches_subsystem::() { + if !e.x.matches_subsystem::() { return None; } let entry = e.write(); @@ -483,6 +484,7 @@ impl Descriptors { .as_ref() .unwrap() .x + .entry .write() .metadata .insert(metadata) @@ -519,7 +521,7 @@ impl Descriptors { /// A handle to a descriptor entry (via [`Descriptors::entry_handle`]) that can be used without /// maintaining access to the descriptor table itself. pub struct EntryHandle( - Arc>, + Arc>, PhantomData, ); impl @@ -532,7 +534,7 @@ impl pub fn get_entry( &self, ) -> impl core::ops::Deref + use<'_, Platform, Subsystem> { - crate::sync::RwLockReadGuard::map(self.0.read(), |e| e.as_subsystem::()) + crate::sync::RwLockReadGuard::map(self.0.entry.read(), |e| e.as_subsystem::()) } /// Get the entry behind this handle mutably. @@ -542,15 +544,17 @@ impl pub fn get_entry_mut( &self, ) -> impl core::ops::DerefMut + use<'_, Platform, Subsystem> { - crate::sync::RwLockWriteGuard::map(self.0.write(), |e| e.as_subsystem_mut::()) + crate::sync::RwLockWriteGuard::map(self.0.entry.write(), |e| { + e.as_subsystem_mut::() + }) } pub fn with_entry(&self, f: impl FnOnce(&Subsystem::Entry) -> R) -> R { - f(self.0.read().as_subsystem::()) + f(self.0.entry.read().as_subsystem::()) } pub fn with_entry_mut(&self, f: impl FnOnce(&mut Subsystem::Entry) -> R) -> R { - f(self.0.write().as_subsystem_mut::()) + f(self.0.entry.write().as_subsystem_mut::()) } } @@ -805,17 +809,17 @@ pub enum MetadataError { /// A module-internal fd-specific individual entry struct IndividualEntry { - x: Arc>, + x: Arc>, metadata: AnyMap, } impl core::ops::Deref for IndividualEntry { - type Target = Arc>; + type Target = RwLock; fn deref(&self) -> &Self::Target { - &self.x + &self.x.entry } } impl IndividualEntry { - fn new(x: Arc>) -> Self { + fn new(x: Arc>) -> Self { Self { x, metadata: AnyMap::new(), @@ -823,6 +827,24 @@ impl IndividualEntry { } } +struct SharedEntry { + subsystem_entry_type: core::any::TypeId, + entry: RwLock, +} + +impl SharedEntry { + fn new(entry: DescriptorEntry) -> Arc { + Arc::new(Self { + subsystem_entry_type: core::any::TypeId::of::(), + entry: RwLock::new(entry), + }) + } + + fn matches_subsystem(&self) -> bool { + self.subsystem_entry_type == core::any::TypeId::of::() + } +} + /// A crate-internal entry for a descriptor. pub(crate) struct DescriptorEntry { entry: alloc::boxed::Box,