package ptrproxy //#include import ( "C" ) import ( "sync" "unsafe" ) // PtrProxy creates a safe pointer registry. It hangs on to an unsafe.Pointer and // returns a totally-safe unsafe.Pointer ID that can be used to look up the original // pointer by using it. var ( mutex sync.RWMutex lookup map[unsafe.Pointer]unsafe.Pointer = map[unsafe.Pointer]unsafe.Pointer{} ) // Ref registers the given pointer and returns a corresponding id that can be // used to retrieve it later. func Ref(ptr unsafe.Pointer) unsafe.Pointer { if ptr == nil { return nil } var cptr unsafe.Pointer = C.malloc(C.size_t(1)) if cptr == nil { return nil } mutex.Lock() lookup[cptr] = ptr mutex.Unlock() return cptr } // Deref takes an id and returns the corresponding pointer if it exists. func Deref(ptr unsafe.Pointer) (unsafe.Pointer, bool) { if ptr == nil { return nil, false } mutex.RLock() val, ok := lookup[ptr] mutex.RUnlock() return val, ok } // Deref and Free func Move(ptr unsafe.Pointer) (unsafe.Pointer, bool) { if ptr == nil { return nil, false } mutex.Lock() val, ok := lookup[ptr] if ok == false { mutex.Unlock() return nil, false } else { delete(lookup, ptr) mutex.Unlock() C.free(ptr) return val, true } } // Free releases a registered pointer by its id. func Free(ptr unsafe.Pointer) { if ptr == nil { return } mutex.Lock() delete(lookup, ptr) mutex.Unlock() C.free(ptr) } // This like https://github.com/mattn/go-pointer // https://github.com/shazow/gohttplib/blob/master/ptrproxy.go