use alloc::{ collections::LinkedList, sync::{Arc, Weak}, vec::Vec, }; use system_error::SystemError; use crate::{ libs::{spinlock::SpinLock, wait_queue::EventWaitQueue}, net::event_poll::{EPollEventType, EPollItem, EventPoll}, process::ProcessManager, sched::{schedule, SchedMode}, }; #[derive(Debug, Clone)] pub struct EPollItems { items: Arc>>>, } impl Default for EPollItems { fn default() -> Self { Self { items: Arc::new(SpinLock::new(LinkedList::new())), } } } impl EPollItems { pub fn add(&self, item: Arc) { self.items.lock_irqsave().push_back(item); } pub fn remove(&self, item: &Weak>) -> Result<(), SystemError> { let to_remove = self .items .lock_irqsave() .extract_if(|x| x.epoll().ptr_eq(item)) .collect::>(); let result = if !to_remove.is_empty() { Ok(()) } else { Err(SystemError::ENOENT) }; drop(to_remove); return result; } pub fn clear(&self) -> Result<(), SystemError> { let mut guard = self.items.lock_irqsave(); let mut result = Ok(()); guard.iter().for_each(|item| { if let Some(epoll) = item.epoll().upgrade() { let _ = EventPoll::ep_remove(&mut epoll.lock_irqsave(), item.fd(), None).map_err(|e| { result = Err(e); }); } }); guard.clear(); return result; } }