From: Hraban Luyat Date: Fri, 10 Jul 2020 08:37:18 +0000 (+0100) Subject: fix: wrap libopusfile init call for go test -race X-Git-Tag: v2.0.0~18 X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=2a2b57e79dfdd65379ab4626b58f82cfbd3ba11f;p=go-opus.git fix: wrap libopusfile init call for go test -race Since go 1.14 the race checker includes an overzealous pointer checker. It marks all conversions from uintptr to unsafe.Pointer as an error, but in reality that's allowed as long as you never dereference the pointer or do any arithmetic on it. The C compiler doesn't complain about this, so we pass the uintptr value to C and convert it there, in a small wrapper function. See https://groups.google.com/g/golang-nuts/c/995uZyRPKlU for more details. Fixes hraban/opus#28 --- diff --git a/callbacks.c b/callbacks.c index caa7c0d..5645f30 100644 --- a/callbacks.c +++ b/callbacks.c @@ -6,6 +6,7 @@ // plays nice with the CGo rules and avoids any confusion. #include +#include // Defined in Go. Uses the same signature as Go, no need for proxy function. int go_readcallback(void *p, unsigned char *buf, int nbytes); @@ -15,3 +16,14 @@ int go_readcallback(void *p, unsigned char *buf, int nbytes); struct OpusFileCallbacks callbacks = { .read = go_readcallback, }; + +// Proxy function for op_open_callbacks, because it takes a void * context but +// we want to pass it non-pointer data, namely an arbitrary uintptr_t +// value. This is legal C, but go test -race (-d=checkptr) complains anyway. So +// we have this wrapper function to shush it. +// https://groups.google.com/g/golang-nuts/c/995uZyRPKlU +OggOpusFile * +my_open_callbacks(uintptr_t p, const OpusFileCallbacks *cb, int *error) +{ + return op_open_callbacks((void *)p, cb, NULL, 0, error); +} diff --git a/stream.go b/stream.go index 208a0bc..60f99e0 100644 --- a/stream.go +++ b/stream.go @@ -13,9 +13,11 @@ import ( /* #cgo pkg-config: opusfile #include +#include #include extern struct OpusFileCallbacks callbacks; +OggOpusFile *my_open_callbacks(uintptr_t p, const OpusFileCallbacks *cb, int *error); */ import "C" @@ -103,13 +105,7 @@ func (s *Stream) Init(read io.Reader) error { // called. streams.Save(s) defer streams.Del(s) - oggfile := C.op_open_callbacks( - // "C code may not keep a copy of a Go pointer after the call returns." - unsafe.Pointer(s.id), - &C.callbacks, - nil, - 0, - &errno) + oggfile := C.my_open_callbacks(C.uintptr_t(s.id), &C.callbacks, &errno) if errno != 0 { return StreamError(errno) }