cutil: add SyncBuffer abstraction layer to PtrGuard

In order to be able to swich on and off PtrGuard usage, SyncBuffer
implements a typical usage pattern of PtrGuard, that is a data buffer
referenced from inside a C allocated struct, in two ways: 1) using a
PtrGuard to dierctly store a pointer to the Go buffer in C memory, or
2) allocating a C buffer of same size and syncing data back with
C.memcpy().  The implementation can be chosen with the with_ptrguard
build tag.

Signed-off-by: Sven Anderson <sven@redhat.com>
This commit is contained in:
Sven Anderson 2021-01-16 21:07:12 +01:00 committed by John Mulligan
parent ac57250a5b
commit 430dea5b7f
2 changed files with 65 additions and 0 deletions

View File

@ -0,0 +1,28 @@
// +build ptrguard
package cutil
import (
"unsafe"
)
// SyncBuffer is a C buffer connected to a data slice
type SyncBuffer struct {
pg *PtrGuard
}
// NewSyncBuffer creates a C buffer from a data slice and stores it at CPtr
func NewSyncBuffer(cPtr CPtr, data []byte) *SyncBuffer {
var v SyncBuffer
v.pg = NewPtrGuard(cPtr, unsafe.Pointer(&data[0]))
return &v
}
// Release releases the C buffer and nulls its stored pointer
func (v *SyncBuffer) Release() {
v.pg.Release()
}
// Sync asserts that changes in the C buffer are available in the data
// slice
func (v *SyncBuffer) Sync() {}

View File

@ -0,0 +1,37 @@
// +build !ptrguard
package cutil
// SyncBuffer is a C buffer connected to a data slice
type SyncBuffer struct {
data []byte
cPtr *CPtr
}
// NewSyncBuffer creates a C buffer from a data slice and stores it at CPtr
func NewSyncBuffer(cPtr CPtr, data []byte) *SyncBuffer {
var v SyncBuffer
v.data = data
v.cPtr = (*CPtr)(cPtr)
*v.cPtr = CBytes(data)
return &v
}
// Release releases the C buffer and nulls its stored pointer
func (v *SyncBuffer) Release() {
if v.cPtr != nil {
Free(*v.cPtr)
*v.cPtr = nil
v.cPtr = nil
}
v.data = nil
}
// Sync asserts that changes in the C buffer are available in the data
// slice
func (v *SyncBuffer) Sync() {
if v.cPtr == nil {
return
}
Memcpy(CPtr(&v.data[0]), CPtr(*v.cPtr), SizeT(len(v.data)))
}