diff options
| author | Carlos Martín Nieto <[email protected]> | 2016-02-18 20:11:54 +0100 |
|---|---|---|
| committer | Carlos Martín Nieto <[email protected]> | 2016-02-18 20:11:54 +0100 |
| commit | 6941cccb6959195a0a615e99322689c640427c8a (patch) | |
| tree | 2039894b37f409db0dd2f3d6ce91716e6830e057 | |
| parent | ac719c675907a3185bdcebfe8329bde90d354aea (diff) | |
| parent | fa644d2fc9efa3baee93b525212d76dfa17a5db5 (diff) | |
Merge branch 'master' into next
| -rw-r--r-- | handles.go | 56 |
1 files changed, 15 insertions, 41 deletions
@@ -1,5 +1,9 @@ package git +/* +#include <stdlib.h> +*/ +import "C" import ( "fmt" "sync" @@ -9,75 +13,45 @@ import ( type HandleList struct { sync.RWMutex // stores the Go pointers - handles []interface{} - // Indicates which indices are in use. - set map[int]bool + handles map[unsafe.Pointer]interface{} } func NewHandleList() *HandleList { return &HandleList{ - handles: make([]interface{}, 5), - set: make(map[int]bool), + handles: make(map[unsafe.Pointer]interface{}), } } -// findUnusedSlot finds the smallest-index empty space in our -// 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++ { - if !v.set[i] { - return i - } - } - - // reaching here means we've run out of entries so append and - // return the new index, which is equal to the old length. - slot := len(v.handles) - v.handles = append(v.handles, nil) - - return slot -} - // Track adds the given pointer to the list of pointers to track and // returns a pointer value which can be passed to C as an opaque // pointer. func (v *HandleList) Track(pointer interface{}) unsafe.Pointer { - v.Lock() - - slot := v.findUnusedSlot() - v.handles[slot] = pointer - v.set[slot] = true + handle := C.malloc(1) + v.Lock() + v.handles[handle] = pointer v.Unlock() - return unsafe.Pointer(uintptr(slot)) + return handle } // Untrack stops tracking the pointer given by the handle func (v *HandleList) Untrack(handle unsafe.Pointer) { - slot := int(uintptr(handle)) - v.Lock() - - v.handles[slot] = nil - delete(v.set, slot) - + delete(v.handles, handle) + C.free(handle) v.Unlock() } // Get retrieves the pointer from the given handle func (v *HandleList) Get(handle unsafe.Pointer) interface{} { - slot := int(uintptr(handle)) - v.RLock() + defer v.RUnlock() - if !v.set[slot] { + ptr, ok := v.handles[handle] + if !ok { panic(fmt.Sprintf("invalid pointer handle: %p", handle)) } - ptr := v.handles[slot] - - v.RUnlock() - return ptr } |
