Avoid an allocation in epoll

PiperOrigin-RevId: 318346153
This commit is contained in:
Tamir Duberstein
2020-06-25 14:18:33 -07:00
committed by gVisor bot
parent 00ee5abaa7
commit 4069461877
2 changed files with 15 additions and 19 deletions
+14 -18
View File
@@ -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
+1 -1
View File
@@ -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)
}