From e1e1b4b1e164b4aba04e43f8b93c9a552fdc6ab4 Mon Sep 17 00:00:00 2001 From: Dmitri Shuralyov Date: Mon, 6 Jul 2015 19:27:58 -0700 Subject: [PATCH] Prevent slot int variable from being GCed. Before this change, there were no users of slot int variable in the Go world (just a pointer to it that ended up in C world only), so Go's garbage collector would free it and its value could not retrieved later (once a pointer to it comes back to Go world from C world). Keep a pointer to it in the Go world so that does not happen. Fixes #218. --- handles.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/handles.go b/handles.go index ec62a48..a062231 100644 --- a/handles.go +++ b/handles.go @@ -10,14 +10,15 @@ type HandleList struct { sync.RWMutex // stores the Go pointers handles []interface{} - // indicates which indices are in use - set map[int]bool + // Indicates which indices are in use, and keeps a pointer to slot int variable (the handle) + // in the Go world, so that the Go garbage collector does not free it. + set map[int]*int } func NewHandleList() *HandleList { return &HandleList{ 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. func (v *HandleList) findUnusedSlot() int { for i := 1; i < len(v.handles); i++ { - isUsed := v.set[i] + _, isUsed := v.set[i] if !isUsed { return i } @@ -47,7 +48,7 @@ func (v *HandleList) Track(pointer interface{}) unsafe.Pointer { slot := v.findUnusedSlot() 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()