-
Notifications
You must be signed in to change notification settings - Fork 20
/
ptrproxy.go
48 lines (42 loc) · 999 Bytes
/
ptrproxy.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package main
import (
"C"
"sync"
"unsafe"
)
// PtrProxy creates a safe pointer registry. It hangs on to an unsafe.Pointer and
// returns a totally-safe C.uint ID that can be used to look up the original
// pointer by using it.
func PtrProxy() *ptrProxy {
return &ptrProxy{
lookup: map[uint]unsafe.Pointer{},
}
}
type ptrProxy struct {
sync.Mutex
count uint
lookup map[uint]unsafe.Pointer
}
// Ref registers the given pointer and returns a corresponding id that can be
// used to retrieve it later.
func (p *ptrProxy) Ref(ptr unsafe.Pointer) C.uint {
p.Lock()
id := p.count
p.count++
p.lookup[id] = ptr
p.Unlock()
return C.uint(id)
}
// Deref takes an id and returns the corresponding pointer if it exists.
func (p *ptrProxy) Deref(id C.uint) (unsafe.Pointer, bool) {
p.Lock()
val, ok := p.lookup[uint(id)]
p.Unlock()
return val, ok
}
// Free releases a registered pointer by its id.
func (p *ptrProxy) Free(id C.uint) {
p.Lock()
delete(p.lookup, uint(id))
p.Unlock()
}