2
0
mirror of synced 2025-02-24 15:28:28 +00:00
mobile/bind/testdata/structs.go.golden
Elias Naur 07a529f836 mobile/bind: fix a reference count race with the garbage collectors
Each side of the language barrier maintains a map of reference numbers
to objects. Each entry has a reference count that exactly matches
the number of active proxy objects on the other side. When a reference
crosses the barrier, the count is incremented and when a proxy finalizer
is run, the count is decremented. If the count reaches 0, the reference
number and its object are removed from the map.

There is a possibility that a reference number is passed to the other
side, and the last proxy is then immediately garbage collected and
finalized. The reference counter then reaches 0 before the other side has
converted the reference number to its object, crashing the program.

This is possible in both Go/Java/ObjC but is most likely to happen in
ObjC because its own automatic reference count runtime frees objects
as soon as they are statically never referenced again.

Fix the race by always incrementing the reference count before sending
a reference across the barrier. When converting the reference back into
an object on the other side, decrement the counter again.

Only the new ObjC test fails without this fix, but I left the Java
counterpart in for good measure.

Change-Id: I92743aabec275b4a5b82b952052e7e284872ce02
Reviewed-on: https://go-review.googlesource.com/21311
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
2016-03-30 18:24:55 +00:00

145 lines
3.4 KiB
Plaintext

// Package gomobile_bind is an autogenerated binder stub for package structs.
// gobind -lang=go structs
//
// File is generated by gobind. Do not edit.
package gomobile_bind
/*
#include <stdlib.h>
#include <stdint.h>
#include "seq.h"
#include "structs.h"
*/
import "C"
import (
_seq "golang.org/x/mobile/bind/seq"
"structs"
)
// suppress the error if seq ends up unused
var _ = _seq.FromRefNum
//export proxystructs_S_X_Set
func proxystructs_S_X_Set(refnum C.int32_t, v C.double) {
ref := _seq.FromRefNum(int32(refnum))
_v := float64(v)
ref.Get().(*structs.S).X = _v
}
//export proxystructs_S_X_Get
func proxystructs_S_X_Get(refnum C.int32_t) C.double {
ref := _seq.FromRefNum(int32(refnum))
v := ref.Get().(*structs.S).X
_v := C.double(v)
return _v
}
//export proxystructs_S_Y_Set
func proxystructs_S_Y_Set(refnum C.int32_t, v C.double) {
ref := _seq.FromRefNum(int32(refnum))
_v := float64(v)
ref.Get().(*structs.S).Y = _v
}
//export proxystructs_S_Y_Get
func proxystructs_S_Y_Get(refnum C.int32_t) C.double {
ref := _seq.FromRefNum(int32(refnum))
v := ref.Get().(*structs.S).Y
_v := C.double(v)
return _v
}
//export proxystructs_S_Identity
func proxystructs_S_Identity(refnum C.int32_t) (C.int32_t, C.nstring) {
ref := _seq.FromRefNum(int32(refnum))
v := ref.Get().(*structs.S)
res_0, res_1 := v.Identity()
var _res_0 C.int32_t = _seq.NullRefNum
if res_0 != nil {
_res_0 = C.int32_t(_seq.ToRefNum(res_0))
}
var _res_1_str string
if res_1 == nil {
_res_1_str = ""
} else {
_res_1_str = res_1.Error()
}
_res_1 := encodeString(_res_1_str)
return _res_0, _res_1
}
//export proxystructs_S_Sum
func proxystructs_S_Sum(refnum C.int32_t) C.double {
ref := _seq.FromRefNum(int32(refnum))
v := ref.Get().(*structs.S)
res_0 := v.Sum()
_res_0 := C.double(res_0)
return _res_0
}
//export proxystructs_S2_M
func proxystructs_S2_M(refnum C.int32_t) {
ref := _seq.FromRefNum(int32(refnum))
v := ref.Get().(*structs.S2)
v.M()
}
//export proxystructs_S2_String
func proxystructs_S2_String(refnum C.int32_t) C.nstring {
ref := _seq.FromRefNum(int32(refnum))
v := ref.Get().(*structs.S2)
res_0 := v.String()
_res_0 := encodeString(res_0)
return _res_0
}
//export proxystructs_I_M
func proxystructs_I_M(refnum C.int32_t) {
ref := _seq.FromRefNum(int32(refnum))
v := ref.Get().(structs.I)
v.M()
}
type proxystructs_I _seq.Ref
func (p *proxystructs_I) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }
func (p *proxystructs_I) M() {
C.cproxystructs_I_M(C.int32_t(p.Bind_proxy_refnum__()))
}
//export proxystructs__Identity
func proxystructs__Identity(param_s C.int32_t) C.int32_t {
// Must be a Go object
_param_s_ref := _seq.FromRefNum(int32(param_s))
_param_s := _param_s_ref.Get().(*structs.S)
res_0 := structs.Identity(_param_s)
var _res_0 C.int32_t = _seq.NullRefNum
if res_0 != nil {
_res_0 = C.int32_t(_seq.ToRefNum(res_0))
}
return _res_0
}
//export proxystructs__IdentityWithError
func proxystructs__IdentityWithError(param_s C.int32_t) (C.int32_t, C.nstring) {
// Must be a Go object
_param_s_ref := _seq.FromRefNum(int32(param_s))
_param_s := _param_s_ref.Get().(*structs.S)
res_0, res_1 := structs.IdentityWithError(_param_s)
var _res_0 C.int32_t = _seq.NullRefNum
if res_0 != nil {
_res_0 = C.int32_t(_seq.ToRefNum(res_0))
}
var _res_1_str string
if res_1 == nil {
_res_1_str = ""
} else {
_res_1_str = res_1.Error()
}
_res_1 := encodeString(_res_1_str)
return _res_0, _res_1
}