Prevent memory leaks in ilist

When list elements are removed from a list but not discarded, it becomes
important to invalidate the references they hold to their former
neighbors to prevent memory leaks.

PiperOrigin-RevId: 299412421
This commit is contained in:
Tamir Duberstein
2020-03-06 12:31:43 -08:00
committed by gVisor bot
parent 18d41cf153
commit 6fa5cee82c
5 changed files with 23 additions and 13 deletions
+6 -2
View File
@@ -169,8 +169,9 @@ func (l *List) InsertBefore(a, e Element) {
// Remove removes e from l.
func (l *List) Remove(e Element) {
prev := ElementMapper{}.linkerFor(e).Prev()
next := ElementMapper{}.linkerFor(e).Next()
linker := ElementMapper{}.linkerFor(e)
prev := linker.Prev()
next := linker.Next()
if prev != nil {
ElementMapper{}.linkerFor(prev).SetNext(next)
@@ -183,6 +184,9 @@ func (l *List) Remove(e Element) {
} else {
l.tail = prev
}
linker.SetNext(nil)
linker.SetPrev(nil)
}
// Entry is a default implementation of Linker. Users can add anonymous fields
-2
View File
@@ -101,8 +101,6 @@ func (c *DirentCache) remove(d *Dirent) {
panic(fmt.Sprintf("trying to remove %v, which is not in the dirent cache", d))
}
c.list.Remove(d)
d.SetPrev(nil)
d.SetNext(nil)
d.DecRef()
c.currentSize--
if c.limit != nil {
+4 -1
View File
@@ -143,7 +143,10 @@ func (i *Inotify) Read(ctx context.Context, _ *File, dst usermem.IOSequence, _ i
}
var writeLen int64
for event := i.events.Front(); event != nil; event = event.Next() {
for it := i.events.Front(); it != nil; {
event := it
it = it.Next()
// Does the buffer have enough remaining space to hold the event we're
// about to write out?
if dst.NumBytes() < int64(event.sizeOf()) {
+8 -5
View File
@@ -38,11 +38,14 @@ func (e *EventPoll) afterLoad() {
}
}
for it := e.waitingList.Front(); it != nil; it = it.Next() {
if it.id.File.Readiness(it.mask) != 0 {
e.waitingList.Remove(it)
e.readyList.PushBack(it)
it.curList = &e.readyList
for it := e.waitingList.Front(); it != nil; {
entry := it
it = it.Next()
if entry.id.File.Readiness(entry.mask) != 0 {
e.waitingList.Remove(entry)
e.readyList.PushBack(entry)
entry.curList = &e.readyList
e.Notify(waiter.EventIn)
}
}
@@ -115,10 +115,12 @@ func (f *Fragmentation) Process(id uint32, first, last uint16, more bool, vv buf
// Evict reassemblers if we are consuming more memory than highLimit until
// we reach lowLimit.
if f.size > f.highLimit {
tail := f.rList.Back()
for f.size > f.lowLimit && tail != nil {
for f.size > f.lowLimit {
tail := f.rList.Back()
if tail == nil {
break
}
f.release(tail)
tail = tail.Prev()
}
}
f.mu.Unlock()