Skip to content

Commit e1e1b4b

Browse files
committed
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.
1 parent 4eae20e commit e1e1b4b

File tree

1 file changed

+6
-5
lines changed

1 file changed

+6
-5
lines changed

handles.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,23 @@ type HandleList struct {
1010
sync.RWMutex
1111
// stores the Go pointers
1212
handles []interface{}
13-
// indicates which indices are in use
14-
set map[int]bool
13+
// Indicates which indices are in use, and keeps a pointer to slot int variable (the handle)
14+
// in the Go world, so that the Go garbage collector does not free it.
15+
set map[int]*int
1516
}
1617

1718
func NewHandleList() *HandleList {
1819
return &HandleList{
1920
handles: make([]interface{}, 5),
20-
set: make(map[int]bool),
21+
set: make(map[int]*int),
2122
}
2223
}
2324

2425
// findUnusedSlot finds the smallest-index empty space in our
2526
// list. You must only run this function while holding a write lock.
2627
func (v *HandleList) findUnusedSlot() int {
2728
for i := 1; i < len(v.handles); i++ {
28-
isUsed := v.set[i]
29+
_, isUsed := v.set[i]
2930
if !isUsed {
3031
return i
3132
}
@@ -47,7 +48,7 @@ func (v *HandleList) Track(pointer interface{}) unsafe.Pointer {
4748

4849
slot := v.findUnusedSlot()
4950
v.handles[slot] = pointer
50-
v.set[slot] = true
51+
v.set[slot] = &slot // Keep a pointer to slot in Go world, so it's not freed by GC.
5152

5253
v.Unlock()
5354

0 commit comments

Comments
 (0)