diff options
| author | Dmitri Shuralyov <[email protected]> | 2015-07-06 19:27:58 -0700 |
|---|---|---|
| committer | Dmitri Shuralyov <[email protected]> | 2015-07-26 15:02:40 -0700 |
| commit | e1e1b4b1e164b4aba04e43f8b93c9a552fdc6ab4 (patch) | |
| tree | 3fbdb147c4a52ef0811ffe869fb9a0324469915e | |
| parent | 4eae20ec279d20948aa5a45e0963ae7c4bcb0712 (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.
| -rw-r--r-- | handles.go | 11 |
1 files changed, 6 insertions, 5 deletions
@@ -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() |
