Merge pull request #231 from shurcooL/master-fix-HandleList-Track-gc-issue

[master] Prevent slot int variable from being GCed.
This commit is contained in:
Carlos Martín Nieto 2015-07-28 08:09:01 +02:00
commit f2d8797a96
1 changed files with 6 additions and 5 deletions

View File

@ -10,14 +10,15 @@ type HandleList struct {
sync.RWMutex sync.RWMutex
// stores the Go pointers // stores the Go pointers
handles []interface{} handles []interface{}
// indicates which indices are in use // Indicates which indices are in use, and keeps a pointer to slot int variable (the handle)
set map[int]bool // in the Go world, so that the Go garbage collector does not free it.
set map[int]*int
} }
func NewHandleList() *HandleList { func NewHandleList() *HandleList {
return &HandleList{ return &HandleList{
handles: make([]interface{}, 5), handles: make([]interface{}, 5),
set: make(map[int]bool), set: make(map[int]*int),
} }
} }
@ -25,7 +26,7 @@ func NewHandleList() *HandleList {
// list. You must only run this function while holding a write lock. // list. You must only run this function while holding a write lock.
func (v *HandleList) findUnusedSlot() int { func (v *HandleList) findUnusedSlot() int {
for i := 1; i < len(v.handles); i++ { for i := 1; i < len(v.handles); i++ {
isUsed := v.set[i] _, isUsed := v.set[i]
if !isUsed { if !isUsed {
return i return i
} }
@ -47,7 +48,7 @@ func (v *HandleList) Track(pointer interface{}) unsafe.Pointer {
slot := v.findUnusedSlot() slot := v.findUnusedSlot()
v.handles[slot] = pointer v.handles[slot] = pointer
v.set[slot] = true v.set[slot] = &slot // Keep a pointer to slot in Go world, so it's not freed by GC.
v.Unlock() v.Unlock()