introducing keep alives, where necessary

This commit is contained in:
Sebastian Borchers 2019-01-28 09:47:32 +01:00
parent d1c4dcdcf7
commit 0b45bb5544
4 changed files with 19 additions and 17 deletions

2
app.go
View File

@ -235,7 +235,7 @@ func (a *app) AddImageProvider(id string, ip *ImageProvider) error {
var ret C.int
a.RunMain(func() {
ret = C.gml_app_add_imageprovider(a.app, idC, ip.ip, apiErr.err)
ret = C.gml_app_add_imageprovider(a.app, idC, ip.ptr, apiErr.err)
})
if ret != 0 {
return apiErr.Err("failed to add image provider")

View File

@ -40,7 +40,7 @@ import (
type Image struct {
freed bool
img C.gml_image
ptr C.gml_image
}
func NewImage() (img *Image) {
@ -56,7 +56,7 @@ func newImage(imgC C.gml_image, free bool) (img *Image) {
img = &Image{
freed: !free,
img: imgC,
ptr: imgC,
}
// Always free the C++ value if defined so.
@ -72,7 +72,7 @@ func freeImage(img *Image) {
return
}
img.freed = true
C.gml_image_free(img.img)
C.gml_image_free(img.ptr)
}
func (img *Image) Free() {
@ -81,7 +81,7 @@ func (img *Image) Free() {
// Reset the image to an empty image.
func (img *Image) Reset() {
C.gml_image_reset(img.img)
C.gml_image_reset(img.ptr)
// Prevent the GC from freeing. Go issue 13347
runtime.KeepAlive(img)
@ -89,7 +89,7 @@ func (img *Image) Reset() {
// SetTo performs a shallow copy.
func (img *Image) SetTo(other *Image) {
C.gml_image_set_to(img.img, other.img)
C.gml_image_set_to(img.ptr, other.ptr)
// Prevent the GC from freeing. Go issue 13347
runtime.KeepAlive(img)
@ -116,7 +116,7 @@ func (img *Image) LoadFromGoImage(gimg image.Image) error {
defer errorPool.Put(apiErr)
ret := C.gml_image_load_from_rgba(
img.img,
img.ptr,
(*C.char)(unsafe.Pointer(&imgRGBA.Pix[0])),
C.int(len(imgRGBA.Pix)),
C.int(b.Dx()),
@ -146,7 +146,7 @@ func (img *Image) LoadFromFile(filename string) error {
apiErr := errorPool.Get()
defer errorPool.Put(apiErr)
ret := C.gml_image_load_from_file(img.img, filenameC, apiErr.err)
ret := C.gml_image_load_from_file(img.ptr, filenameC, apiErr.err)
if ret != 0 {
return apiErr.Err("failed to load from file")
}
@ -165,7 +165,7 @@ func (img *Image) LoadFromData(data []byte) error {
apiErr := errorPool.Get()
defer errorPool.Put(apiErr)
ret := C.gml_image_load_from_data(img.img, (*C.char)(unsafe.Pointer(&data[0])), C.int(len(data)), apiErr.err)
ret := C.gml_image_load_from_data(img.ptr, (*C.char)(unsafe.Pointer(&data[0])), C.int(len(data)), apiErr.err)
if ret != 0 {
return apiErr.Err("failed to load from data")
}

View File

@ -65,8 +65,8 @@ type ImageProviderCallback func(id string, img *Image) error
type ImageProvider struct {
freed bool
ip C.gml_image_provider
ptr unsafe.Pointer
ptr C.gml_image_provider
goPtr unsafe.Pointer
callback ImageProviderCallback
}
@ -79,15 +79,15 @@ func NewImageProvider(
ip := &ImageProvider{
callback: callback,
}
ip.ptr = pointer.Save(ip)
ip.ip = C.gml_image_provider_new(ip.ptr, C.int(aspectRatioMode), C.int(transformMode))
ip.goPtr = pointer.Save(ip)
ip.ptr = C.gml_image_provider_new(ip.goPtr, C.int(aspectRatioMode), C.int(transformMode))
// Always free the C++ value.
runtime.SetFinalizer(ip, freeImageProvider)
// Check if something failed.
// This should never happen. Otherwise this signalizes a fatal error.
if ip.ip == nil {
if ip.ptr == nil {
panic(fmt.Errorf("failed to create gml imageprovider: C pointer is nil"))
}
@ -99,8 +99,8 @@ func freeImageProvider(ip *ImageProvider) {
return
}
ip.freed = true
C.gml_image_provider_free(ip.ip)
pointer.Unref(ip.ptr)
C.gml_image_provider_free(ip.ptr)
pointer.Unref(ip.goPtr)
}
func (ip *ImageProvider) Free() {
@ -139,7 +139,6 @@ func gml_image_provider_request_go_slot(
// Emit the finished signal on the image response.
// Must always be triggered!
// TODO: should run on main?
C.gml_image_response_emit_finished(imgResp, errStrC)
}()
}

View File

@ -111,6 +111,9 @@ func ToVariant(i interface{}) *Variant {
}
}
// Prevent the GC from freeing. Go issue 13347
runtime.KeepAlive(i)
return newVariant(ptr)
}