sync.go raw

   1  package cgo
   2  
   3  import (
   4  	"sync"
   5  	"unsafe"
   6  )
   7  
   8  // #include <stdlib.h>
   9  import "C"
  10  
  11  // refMap is a convenient way to store opaque references that can be passed to
  12  // C. It is useful if an API uses function pointers and you cannot pass a Go
  13  // pointer but only a C pointer.
  14  type refMap struct {
  15  	refs map[unsafe.Pointer]interface{}
  16  	lock sync.Mutex
  17  }
  18  
  19  // Put stores a value in the map. It can later be retrieved using Get. It must
  20  // be removed using Remove to avoid memory leaks.
  21  func (m *refMap) Put(v interface{}) unsafe.Pointer {
  22  	m.lock.Lock()
  23  	defer m.lock.Unlock()
  24  	if m.refs == nil {
  25  		m.refs = make(map[unsafe.Pointer]interface{}, 1)
  26  	}
  27  	ref := C.malloc(1)
  28  	m.refs[ref] = v
  29  	return ref
  30  }
  31  
  32  // Get returns a stored value previously inserted with Put. Use the same
  33  // reference as you got from Put.
  34  func (m *refMap) Get(ref unsafe.Pointer) interface{} {
  35  	m.lock.Lock()
  36  	defer m.lock.Unlock()
  37  	return m.refs[ref]
  38  }
  39  
  40  // Remove deletes a single reference from the map.
  41  func (m *refMap) Remove(ref unsafe.Pointer) {
  42  	m.lock.Lock()
  43  	defer m.lock.Unlock()
  44  	delete(m.refs, ref)
  45  	C.free(ref)
  46  }
  47