github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/cgo/sync.go (about)

     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  }