summaryrefslogtreecommitdiff
path: root/handles.go
diff options
context:
space:
mode:
authorDmitri Shuralyov <[email protected]>2015-07-06 19:27:58 -0700
committerDmitri Shuralyov <[email protected]>2015-07-06 19:27:58 -0700
commitb5693c1429ad7247ce75b23ebb866f9428bde8b6 (patch)
treeb19bd2924559eecf38330a9c1e1b6dd9f6ce085f /handles.go
parentb4ade2b9c693488aead837a36bc50e86d04950a2 (diff)
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.
Diffstat (limited to 'handles.go')
-rw-r--r--handles.go11
1 files 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()