How to tell cgo to mark a []byte for garbage collection?

487 views Asked by At

I am calling the following C function from Go:

char *my_read(int dd) {
    char *buf = malloc(sizeof(char) * BUF_SUZE);

    if (!buf) {
        return NULL; // cannot allocate memory
    }

    while (read(dd, buf, BUF_SIZE) < 0) {
        if (errno == EAGAIN || errno == EINTR) {
            continue;
        }
        break;
    }

    return buf;
}

My Go code looks like this:

//#include "hci_cgo.h"
import "C"

func MyRead(dd int) ([]byte, error) {
    data, err := C.my_read(dd)
    if err != nil {
        return nil, err
    }
    if data == nil {
        return nil, errors.New("my_read: cannot allocate memory")
    }
    // Here we create a Go slice of the data, but the C buffer is kept forever:
    return C.GoBytes(unsafe.Pointer(data), C.BUF_SIZE)
}

How should I modify MyRead (or the corresponding C code) to free the allocated buffer before returning from MyRead?

Alternatively, can I re-use a single buffer in C, and thus avoid allocation altogether, and create Go []byte copies of the data after C.my_read(…) returns? If so, I could put a mutex in MyRead to ensure sequential calls to C.my_read(…), but how do I copy the C buffer to Go so that the GC would know about it?

0

There are 0 answers