aboutsummaryrefslogtreecommitdiffhomepage
path: root/cgo/sync.go
blob: 64eab30bee891e593c27588fffe38dc1b39cfe4a (plain)
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
package cgo

import (
	"sync"
	"unsafe"
)

// #include <stdlib.h>
import "C"

// refMap is a convenient way to store opaque references that can be passed to
// C. It is useful if an API uses function pointers and you cannot pass a Go
// pointer but only a C pointer.
type refMap struct {
	refs map[unsafe.Pointer]interface{}
	lock sync.Mutex
}

// Put stores a value in the map. It can later be retrieved using Get. It must
// be removed using Remove to avoid memory leaks.
func (m *refMap) Put(v interface{}) unsafe.Pointer {
	m.lock.Lock()
	defer m.lock.Unlock()
	if m.refs == nil {
		m.refs = make(map[unsafe.Pointer]interface{}, 1)
	}
	ref := C.malloc(1)
	m.refs[ref] = v
	return ref
}

// Get returns a stored value previously inserted with Put. Use the same
// reference as you got from Put.
func (m *refMap) Get(ref unsafe.Pointer) interface{} {
	m.lock.Lock()
	defer m.lock.Unlock()
	return m.refs[ref]
}

// Remove deletes a single reference from the map.
func (m *refMap) Remove(ref unsafe.Pointer) {
	m.lock.Lock()
	defer m.lock.Unlock()
	delete(m.refs, ref)
	C.free(ref)
}