2015-04-21 06:14:22 -05:00
|
|
|
package git
|
|
|
|
|
2016-02-18 10:07:33 -06:00
|
|
|
/*
|
|
|
|
#include <stdlib.h>
|
|
|
|
*/
|
|
|
|
import "C"
|
2015-04-21 06:14:22 -05:00
|
|
|
import (
|
2015-04-24 03:08:32 -05:00
|
|
|
"fmt"
|
2015-04-21 06:14:22 -05:00
|
|
|
"sync"
|
|
|
|
"unsafe"
|
|
|
|
)
|
|
|
|
|
|
|
|
type HandleList struct {
|
2021-09-05 15:59:36 -05:00
|
|
|
doNotCompare
|
2015-04-21 06:14:22 -05:00
|
|
|
sync.RWMutex
|
|
|
|
// stores the Go pointers
|
2016-02-18 10:07:33 -06:00
|
|
|
handles map[unsafe.Pointer]interface{}
|
2015-04-21 06:14:22 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewHandleList() *HandleList {
|
|
|
|
return &HandleList{
|
2016-02-18 10:07:33 -06:00
|
|
|
handles: make(map[unsafe.Pointer]interface{}),
|
2015-04-21 06:14:22 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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 {
|
2016-02-18 10:07:33 -06:00
|
|
|
handle := C.malloc(1)
|
2015-04-21 06:14:22 -05:00
|
|
|
|
2016-02-18 10:07:33 -06:00
|
|
|
v.Lock()
|
|
|
|
v.handles[handle] = pointer
|
2015-04-21 06:14:22 -05:00
|
|
|
v.Unlock()
|
|
|
|
|
2016-02-18 10:07:33 -06:00
|
|
|
return handle
|
2015-04-21 06:14:22 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// Untrack stops tracking the pointer given by the handle
|
|
|
|
func (v *HandleList) Untrack(handle unsafe.Pointer) {
|
|
|
|
v.Lock()
|
2016-02-18 10:07:33 -06:00
|
|
|
delete(v.handles, handle)
|
|
|
|
C.free(handle)
|
2015-04-21 06:14:22 -05:00
|
|
|
v.Unlock()
|
|
|
|
}
|
|
|
|
|
2020-06-21 08:44:06 -05:00
|
|
|
// Clear stops tracking all the managed pointers.
|
|
|
|
func (v *HandleList) Clear() {
|
|
|
|
v.Lock()
|
|
|
|
for handle := range v.handles {
|
|
|
|
delete(v.handles, handle)
|
|
|
|
C.free(handle)
|
|
|
|
}
|
|
|
|
v.Unlock()
|
|
|
|
}
|
|
|
|
|
2015-04-21 06:14:22 -05:00
|
|
|
// Get retrieves the pointer from the given handle
|
|
|
|
func (v *HandleList) Get(handle unsafe.Pointer) interface{} {
|
|
|
|
v.RLock()
|
2016-02-18 10:07:33 -06:00
|
|
|
defer v.RUnlock()
|
2015-04-21 06:14:22 -05:00
|
|
|
|
2016-02-18 10:07:33 -06:00
|
|
|
ptr, ok := v.handles[handle]
|
|
|
|
if !ok {
|
2015-04-24 03:08:32 -05:00
|
|
|
panic(fmt.Sprintf("invalid pointer handle: %p", handle))
|
2015-04-21 06:14:22 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return ptr
|
|
|
|
}
|