mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Avoid an allocation in epoll
PiperOrigin-RevId: 318346153
This commit is contained in:
committed by
gVisor bot
parent
00ee5abaa7
commit
4069461877
@@ -107,7 +107,7 @@ type EventPoll struct {
|
||||
// different lock to avoid circular lock acquisition order involving
|
||||
// the wait queue mutexes and mu. The full order is mu, observed file
|
||||
// wait queue mutex, then listsMu; this allows listsMu to be acquired
|
||||
// when readyCallback is called.
|
||||
// when (*pollEntry).Callback is called.
|
||||
//
|
||||
// An entry is always in one of the following lists:
|
||||
// readyList -- when there's a chance that it's ready to have
|
||||
@@ -116,7 +116,7 @@ type EventPoll struct {
|
||||
// readEvents() functions always call the entry's file
|
||||
// Readiness() function to confirm it's ready.
|
||||
// waitingList -- when there's no chance that the entry is ready,
|
||||
// so it's waiting for the readyCallback to be called
|
||||
// so it's waiting for the (*pollEntry).Callback to be called
|
||||
// on it before it gets moved to the readyList.
|
||||
// disabledList -- when the entry is disabled. This happens when
|
||||
// a one-shot entry gets delivered via readEvents().
|
||||
@@ -269,23 +269,19 @@ func (e *EventPoll) ReadEvents(max int) []linux.EpollEvent {
|
||||
return ret
|
||||
}
|
||||
|
||||
// readyCallback is called when one of the files we're polling becomes ready. It
|
||||
// moves said file to the readyList if it's currently in the waiting list.
|
||||
type readyCallback struct {
|
||||
context *pollEntry
|
||||
}
|
||||
|
||||
// Callback implements waiter.EntryCallback.Callback.
|
||||
func (r *readyCallback) Callback(*waiter.Entry) {
|
||||
entry := r.context
|
||||
e := entry.epoll
|
||||
//
|
||||
// Callback is called when one of the files we're polling becomes ready. It
|
||||
// moves said file to the readyList if it's currently in the waiting list.
|
||||
func (p *pollEntry) Callback(*waiter.Entry) {
|
||||
e := p.epoll
|
||||
|
||||
e.listsMu.Lock()
|
||||
|
||||
if entry.curList == &e.waitingList {
|
||||
e.waitingList.Remove(entry)
|
||||
e.readyList.PushBack(entry)
|
||||
entry.curList = &e.readyList
|
||||
if p.curList == &e.waitingList {
|
||||
e.waitingList.Remove(p)
|
||||
e.readyList.PushBack(p)
|
||||
p.curList = &e.readyList
|
||||
e.listsMu.Unlock()
|
||||
|
||||
e.Notify(waiter.EventIn)
|
||||
@@ -312,7 +308,7 @@ func (e *EventPoll) initEntryReadiness(entry *pollEntry) {
|
||||
// Check if the file happens to already be in a ready state.
|
||||
ready := f.Readiness(entry.mask) & entry.mask
|
||||
if ready != 0 {
|
||||
(&readyCallback{context: entry}).Callback(&entry.waiter)
|
||||
entry.Callback(&entry.waiter)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -384,7 +380,7 @@ func (e *EventPoll) AddEntry(id FileIdentifier, flags EntryFlags, mask waiter.Ev
|
||||
flags: flags,
|
||||
mask: mask,
|
||||
}
|
||||
entry.waiter.Callback = &readyCallback{context: entry}
|
||||
entry.waiter.Callback = entry
|
||||
e.files[id] = entry
|
||||
entry.file = refs.NewWeakRef(id.File, entry)
|
||||
|
||||
@@ -407,7 +403,7 @@ func (e *EventPoll) UpdateEntry(id FileIdentifier, flags EntryFlags, mask waiter
|
||||
}
|
||||
|
||||
// Unregister the old mask and remove entry from the list it's in, so
|
||||
// readyCallback is guaranteed to not be called on this entry anymore.
|
||||
// (*pollEntry).Callback is guaranteed to not be called on this entry anymore.
|
||||
entry.id.File.EventUnregister(&entry.waiter)
|
||||
|
||||
// Remove entry from whatever list it's in. This ensure that no other
|
||||
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
|
||||
// afterLoad is invoked by stateify.
|
||||
func (p *pollEntry) afterLoad() {
|
||||
p.waiter.Callback = &readyCallback{context: p}
|
||||
p.waiter.Callback = p
|
||||
p.file = refs.NewWeakRef(p.id.File, p)
|
||||
p.id.File.EventRegister(&p.waiter, p.mask)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user