mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-16 17:46:48 +00:00
Remove unnecessary is_deleted
This commit is contained in:
parent
bec2c97637
commit
fa52eeb88f
@ -31,7 +31,7 @@ pub struct EpollFile {
|
|||||||
// All interesting entries.
|
// All interesting entries.
|
||||||
interest: Mutex<BTreeMap<FileDesc, Arc<EpollEntry>>>,
|
interest: Mutex<BTreeMap<FileDesc, Arc<EpollEntry>>>,
|
||||||
// Entries that are probably ready (having events happened).
|
// Entries that are probably ready (having events happened).
|
||||||
ready: Mutex<VecDeque<Arc<EpollEntry>>>,
|
ready: Mutex<VecDeque<Weak<EpollEntry>>>,
|
||||||
// EpollFile itself is also pollable
|
// EpollFile itself is also pollable
|
||||||
pollee: Pollee,
|
pollee: Pollee,
|
||||||
// Any EpollFile is wrapped with Arc when created.
|
// Any EpollFile is wrapped with Arc when created.
|
||||||
@ -104,10 +104,10 @@ impl EpollFile {
|
|||||||
// But unfortunately, deleting an entry from the ready list has a
|
// But unfortunately, deleting an entry from the ready list has a
|
||||||
// complexity of O(N).
|
// complexity of O(N).
|
||||||
//
|
//
|
||||||
// To optimize the performance, we only mark the epoll entry as
|
// To optimize performance, we postpone the actual deletion to the time
|
||||||
// deleted at this moment. The real deletion happens when the ready list
|
// when the ready list is scanned in `EpolFile::wait`. This can be done
|
||||||
// is scanned in EpolFile::wait.
|
// because the strong reference count will reach zero and `Weak::upgrade`
|
||||||
entry.set_deleted();
|
// will fail.
|
||||||
|
|
||||||
let file = match entry.file() {
|
let file = match entry.file() {
|
||||||
Some(file) => file,
|
Some(file) => file,
|
||||||
@ -132,9 +132,6 @@ impl EpollFile {
|
|||||||
let entry = interest
|
let entry = interest
|
||||||
.get(&fd)
|
.get(&fd)
|
||||||
.ok_or_else(|| Error::with_message(Errno::ENOENT, "fd is not in the interest list"))?;
|
.ok_or_else(|| Error::with_message(Errno::ENOENT, "fd is not in the interest list"))?;
|
||||||
if entry.is_deleted() {
|
|
||||||
return_errno_with_message!(Errno::ENOENT, "fd is not in the interest list");
|
|
||||||
}
|
|
||||||
let new_mask = new_ep_event.events;
|
let new_mask = new_ep_event.events;
|
||||||
entry.update(new_ep_event, new_ep_flags);
|
entry.update(new_ep_event, new_ep_flags);
|
||||||
let entry = entry.clone();
|
let entry = entry.clone();
|
||||||
@ -203,13 +200,10 @@ impl EpollFile {
|
|||||||
|
|
||||||
fn push_ready(&self, entry: Arc<EpollEntry>) {
|
fn push_ready(&self, entry: Arc<EpollEntry>) {
|
||||||
let mut ready = self.ready.lock();
|
let mut ready = self.ready.lock();
|
||||||
if entry.is_deleted() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if !entry.is_ready() {
|
if !entry.is_ready() {
|
||||||
entry.set_ready();
|
entry.set_ready();
|
||||||
ready.push_back(entry);
|
ready.push_back(Arc::downgrade(&entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Even if the entry is already set to ready, there might be new events that we are interested in.
|
// Even if the entry is already set to ready, there might be new events that we are interested in.
|
||||||
@ -233,7 +227,7 @@ impl EpollFile {
|
|||||||
}
|
}
|
||||||
let ready_entries: Vec<Arc<EpollEntry>> = ready
|
let ready_entries: Vec<Arc<EpollEntry>> = ready
|
||||||
.drain(..pop_count)
|
.drain(..pop_count)
|
||||||
.filter(|entry| !entry.is_deleted())
|
.filter_map(|entry| Weak::upgrade(&entry))
|
||||||
.collect();
|
.collect();
|
||||||
pop_quota -= pop_count;
|
pop_quota -= pop_count;
|
||||||
|
|
||||||
@ -262,7 +256,7 @@ impl EpollFile {
|
|||||||
// If the epoll entry is neither edge-triggered or one-shot, then we should
|
// If the epoll entry is neither edge-triggered or one-shot, then we should
|
||||||
// keep the entry in the ready list.
|
// keep the entry in the ready list.
|
||||||
if !ep_flags.intersects(EpollFlags::ONE_SHOT | EpollFlags::EDGE_TRIGGER) {
|
if !ep_flags.intersects(EpollFlags::ONE_SHOT | EpollFlags::EDGE_TRIGGER) {
|
||||||
ready.push_back(entry);
|
ready.push_back(Arc::downgrade(&entry));
|
||||||
}
|
}
|
||||||
// Otherwise, the entry is indeed removed the ready list and we should reset
|
// Otherwise, the entry is indeed removed the ready list and we should reset
|
||||||
// its ready flag.
|
// its ready flag.
|
||||||
@ -307,7 +301,6 @@ impl Drop for EpollFile {
|
|||||||
let fds: Vec<_> = interest
|
let fds: Vec<_> = interest
|
||||||
.extract_if(|_, _| true)
|
.extract_if(|_, _| true)
|
||||||
.map(|(fd, entry)| {
|
.map(|(fd, entry)| {
|
||||||
entry.set_deleted();
|
|
||||||
if let Some(file) = entry.file() {
|
if let Some(file) = entry.file() {
|
||||||
let _ = file.unregister_observer(&(entry.self_weak() as _));
|
let _ = file.unregister_observer(&(entry.self_weak() as _));
|
||||||
}
|
}
|
||||||
@ -366,8 +359,6 @@ pub struct EpollEntry {
|
|||||||
inner: Mutex<Inner>,
|
inner: Mutex<Inner>,
|
||||||
// Whether the entry is in the ready list
|
// Whether the entry is in the ready list
|
||||||
is_ready: AtomicBool,
|
is_ready: AtomicBool,
|
||||||
// Whether the entry has been deleted from the interest list
|
|
||||||
is_deleted: AtomicBool,
|
|
||||||
// Refers to the epoll file containing this epoll entry
|
// Refers to the epoll file containing this epoll entry
|
||||||
weak_epoll: Weak<EpollFile>,
|
weak_epoll: Weak<EpollFile>,
|
||||||
// An EpollEntry is always contained inside Arc
|
// An EpollEntry is always contained inside Arc
|
||||||
@ -393,7 +384,6 @@ impl EpollEntry {
|
|||||||
file,
|
file,
|
||||||
inner: Mutex::new(Inner { event, flags }),
|
inner: Mutex::new(Inner { event, flags }),
|
||||||
is_ready: AtomicBool::new(false),
|
is_ready: AtomicBool::new(false),
|
||||||
is_deleted: AtomicBool::new(false),
|
|
||||||
weak_epoll,
|
weak_epoll,
|
||||||
weak_self: me.clone(),
|
weak_self: me.clone(),
|
||||||
})
|
})
|
||||||
@ -471,16 +461,6 @@ impl EpollEntry {
|
|||||||
self.is_ready.store(false, Ordering::Relaxed)
|
self.is_ready.store(false, Ordering::Relaxed)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns whether the epoll entry has been deleted from the interest list.
|
|
||||||
pub fn is_deleted(&self) -> bool {
|
|
||||||
self.is_deleted.load(Ordering::Relaxed)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Mark the epoll entry as having been deleted from the interest list.
|
|
||||||
pub fn set_deleted(&self) {
|
|
||||||
self.is_deleted.store(true, Ordering::Relaxed);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the file descriptor associated with the epoll entry.
|
/// Get the file descriptor associated with the epoll entry.
|
||||||
pub fn fd(&self) -> FileDesc {
|
pub fn fd(&self) -> FileDesc {
|
||||||
self.fd
|
self.fd
|
||||||
@ -489,11 +469,6 @@ impl EpollEntry {
|
|||||||
|
|
||||||
impl Observer<IoEvents> for EpollEntry {
|
impl Observer<IoEvents> for EpollEntry {
|
||||||
fn on_events(&self, _events: &IoEvents) {
|
fn on_events(&self, _events: &IoEvents) {
|
||||||
// Fast path
|
|
||||||
if self.is_deleted() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(epoll_file) = self.epoll_file() {
|
if let Some(epoll_file) = self.epoll_file() {
|
||||||
epoll_file.push_ready(self.self_arc());
|
epoll_file.push_ready(self.self_arc());
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user