In old conservative Go, this could cause memory leaks.
A new pickier collector might reasonably crash when it saw one of these.
LGTM=rlh
R=rlh
CC=golang-codereviews
https://golang.org/cl/
147480043
unlock(&c.lock)
recvg := sg.g
- recvg.param = unsafe.Pointer(sg)
if sg.elem != nil {
memmove(unsafe.Pointer(sg.elem), ep, uintptr(c.elemsize))
+ sg.elem = nil
}
+ recvg.param = unsafe.Pointer(sg)
if sg.releasetime != 0 {
sg.releasetime = cputicks()
}
}
panic("send on closed channel")
}
+ gp.param = nil
if mysg.releasetime > 0 {
blockevent(int64(mysg.releasetime)-t0, 2)
}
break
}
gp := sg.g
+ sg.elem = nil
gp.param = nil
if sg.releasetime != 0 {
sg.releasetime = cputicks()
break
}
gp := sg.g
+ sg.elem = nil
gp.param = nil
if sg.releasetime != 0 {
sg.releasetime = cputicks()
if ep != nil {
memmove(ep, sg.elem, uintptr(c.elemsize))
}
+ sg.elem = nil
gp := sg.g
gp.param = unsafe.Pointer(sg)
if sg.releasetime != 0 {
if mysg.releasetime > 0 {
blockevent(mysg.releasetime-t0, 2)
}
+ haveData := gp.param != nil
+ gp.param = nil
releaseSudog(mysg)
- if gp.param != nil {
+ if haveData {
// a sender sent us some data. It already wrote to ep.
selected = true
received = true
c := gomcache()
s := c.sudogcache
if s != nil {
+ if s.elem != nil {
+ gothrow("acquireSudog: found s.elem != nil in cache")
+ }
c.sudogcache = s.next
return s
}
// which keeps the garbage collector from being invoked.
mp := acquirem()
p := new(sudog)
+ if p.elem != nil {
+ gothrow("acquireSudog: found p.elem != nil after new")
+ }
releasem(mp)
return p
}
//go:nosplit
func releaseSudog(s *sudog) {
+ if s.elem != nil {
+ gothrow("runtime: sudog with non-nil elem")
+ }
+ gp := getg()
+ if gp.param != nil {
+ gothrow("runtime: releaseSudog with non-nil gp.param")
+ }
c := gomcache()
s.next = c.sudogcache
c.sudogcache = s
// someone woke us up
sellock(sel)
sg = (*sudog)(gp.param)
+ gp.param = nil
// pass 3 - dequeue from unsuccessful chans
// otherwise they stack up on quiet channels
// iterating through the linked list they are in reverse order.
cas = nil
sglist = gp.waiting
+ // Clear all elem before unlinking from gp.waiting.
+ for sg1 := gp.waiting; sg1 != nil; sg1 = sg1.waitlink {
+ sg1.elem = nil
+ }
gp.waiting = nil
for i := int(sel.ncase) - 1; i >= 0; i-- {
k = &scases[pollorder[i]]
if cas.elem != nil {
memmove(cas.elem, sg.elem, uintptr(c.elemsize))
}
+ sg.elem = nil
gp = sg.g
gp.param = unsafe.Pointer(sg)
if sg.releasetime != 0 {
if sg.elem != nil {
memmove(sg.elem, cas.elem, uintptr(c.elemsize))
}
+ sg.elem = nil
gp = sg.g
gp.param = unsafe.Pointer(sg)
if sg.releasetime != 0 {
} else {
root.head = s.next
}
+ s.elem = nil
s.next = nil
s.prev = nil
}