2
0
mirror of synced 2025-02-24 07:18:15 +00:00
mobile/bind/testdata/vars.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

202 lines
3.6 KiB
Plaintext

// Package gomobile_bind is an autogenerated binder stub for package vars.
// gobind -lang=go vars
//
// File is generated by gobind. Do not edit.
package gomobile_bind
/*
#include <stdlib.h>
#include <stdint.h>
#include "seq.h"
#include "vars.h"
*/
import "C"
import (
_seq "golang.org/x/mobile/bind/seq"
"vars"
)
// suppress the error if seq ends up unused
var _ = _seq.FromRefNum
type proxyvars_I _seq.Ref
func (p *proxyvars_I) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }
//export var_setvars_ABool
func var_setvars_ABool(v C.char) {
_v := v != 0
vars.ABool = _v
}
//export var_getvars_ABool
func var_getvars_ABool() C.char {
v := vars.ABool
var _v C.char = 0
if v {
_v = 1
}
return _v
}
//export var_setvars_AFloat
func var_setvars_AFloat(v C.double) {
_v := float64(v)
vars.AFloat = _v
}
//export var_getvars_AFloat
func var_getvars_AFloat() C.double {
v := vars.AFloat
_v := C.double(v)
return _v
}
//export var_setvars_AFloat32
func var_setvars_AFloat32(v C.float) {
_v := float32(v)
vars.AFloat32 = _v
}
//export var_getvars_AFloat32
func var_getvars_AFloat32() C.float {
v := vars.AFloat32
_v := C.float(v)
return _v
}
//export var_setvars_AFloat64
func var_setvars_AFloat64(v C.double) {
_v := float64(v)
vars.AFloat64 = _v
}
//export var_getvars_AFloat64
func var_getvars_AFloat64() C.double {
v := vars.AFloat64
_v := C.double(v)
return _v
}
//export var_setvars_AString
func var_setvars_AString(v C.nstring) {
_v := decodeString(v)
vars.AString = _v
}
//export var_getvars_AString
func var_getvars_AString() C.nstring {
v := vars.AString
_v := encodeString(v)
return _v
}
//export var_setvars_AStructPtr
func var_setvars_AStructPtr(v C.int32_t) {
// Must be a Go object
_v_ref := _seq.FromRefNum(int32(v))
_v := _v_ref.Get().(*vars.S)
vars.AStructPtr = _v
}
//export var_getvars_AStructPtr
func var_getvars_AStructPtr() C.int32_t {
v := vars.AStructPtr
var _v C.int32_t = _seq.NullRefNum
if v != nil {
_v = C.int32_t(_seq.ToRefNum(v))
}
return _v
}
//export var_setvars_AnInt
func var_setvars_AnInt(v C.nint) {
_v := int(v)
vars.AnInt = _v
}
//export var_getvars_AnInt
func var_getvars_AnInt() C.nint {
v := vars.AnInt
_v := C.nint(v)
return _v
}
//export var_setvars_AnInt16
func var_setvars_AnInt16(v C.int16_t) {
_v := int16(v)
vars.AnInt16 = _v
}
//export var_getvars_AnInt16
func var_getvars_AnInt16() C.int16_t {
v := vars.AnInt16
_v := C.int16_t(v)
return _v
}
//export var_setvars_AnInt32
func var_setvars_AnInt32(v C.int32_t) {
_v := int32(v)
vars.AnInt32 = _v
}
//export var_getvars_AnInt32
func var_getvars_AnInt32() C.int32_t {
v := vars.AnInt32
_v := C.int32_t(v)
return _v
}
//export var_setvars_AnInt64
func var_setvars_AnInt64(v C.int64_t) {
_v := int64(v)
vars.AnInt64 = _v
}
//export var_getvars_AnInt64
func var_getvars_AnInt64() C.int64_t {
v := vars.AnInt64
_v := C.int64_t(v)
return _v
}
//export var_setvars_AnInt8
func var_setvars_AnInt8(v C.int8_t) {
_v := int8(v)
vars.AnInt8 = _v
}
//export var_getvars_AnInt8
func var_getvars_AnInt8() C.int8_t {
v := vars.AnInt8
_v := C.int8_t(v)
return _v
}
//export var_setvars_AnInterface
func var_setvars_AnInterface(v C.int32_t) {
var _v vars.I
_v_ref := _seq.FromRefNum(int32(v))
if _v_ref != nil {
if v < 0 { // go object
_v = _v_ref.Get().(vars.I)
} else { // foreign object
_v = (*proxyvars_I)(_v_ref)
}
}
vars.AnInterface = _v
}
//export var_getvars_AnInterface
func var_getvars_AnInterface() C.int32_t {
v := vars.AnInterface
var _v C.int32_t = _seq.NullRefNum
if v != nil {
_v = C.int32_t(_seq.ToRefNum(v))
}
return _v
}