David Chase
unread,Jul 8, 2015, 1:54:08 PM7/8/15Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to golan...@googlegroups.com
I am not as skilled at Go as I need to be, but I have a lot of experience doing this with other languages.
The other-languages idiom translated into Go would be something along the lines of this:
type ThingWithCbuffer struct {
buf *[4096]C.uchar
// other stuff
}
func finalTWCB(x *ThingWithCbuffer) {
if x.buf != nil {
C.free(x.buf)
x.buf = nil // because we are paranoid
}
}
func makeThingWithCbuffer() *ThingWithCBuffer {
x := &ThingWithCBuffer{}
runtime.setFinalizer(x, finalTWCB)
x.buf = cast_as_necessary(C.malloc(4096))
return x
}
The idea is that the pointer to the C stuff stays allocated until the Go object becomes unreachable, at which point (eventually) GC will occur and (eventually) the object will be queued for finalization.
I use a *[4096]C.uchar to get as much type safety as I can on the Go side and provide as many hints as possible to the compiler about what is going on (right now, it ignores those hints because default behavior is C-friendly). I am told (as a Go compiler writer and officemate of a Go GC writer) that the Go GC will always be prepared to cope with pointers-to-not-Go-heap values stored in Go pointers, so it is okay to store that pointer in a Go struct. By using a pointer to an array I think we obtain type and index safety on the Go side. We prefer to allocate as a C-ish type (as much as possible) to avoid casting Go types (ever) to C types, and in the case of C structs this may eventually be a signal to use a C-friendly layout (as it happens, existing layout rules appear to match C layout rules). I.e., using pointers to and arrays of C types is future-proofing, for some possible futures. Even if it's not necessary for the futures that we end up getting, it will help make it clearer what is going on and also make it clear that problematic idioms (casting *Gotype to *Ctype) don't occur.
I hope I got this right for Go (what I describe has worked fine in other languages in decades past) and I hope it is helpful.