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>
202 lines
3.6 KiB
Plaintext
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
|
|
}
|