github.com/c-darwin/mobile@v0.0.0-20160313183840-ff625c46f7c9/bind/seq/ref.go (about) 1 // Copyright 2014 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package seq 6 7 //#cgo LDFLAGS: -llog 8 //#include <android/log.h> 9 //#include <string.h> 10 //import "C" 11 12 import ( 13 "fmt" 14 "sync" 15 ) 16 17 type countedObj struct { 18 obj interface{} 19 cnt int32 20 } 21 22 // refs stores Go objects that have been passed to another language. 23 var refs struct { 24 sync.Mutex 25 next int32 // next reference number to use for Go object, always negative 26 refs map[interface{}]int32 27 objs map[int32]countedObj 28 } 29 30 func init() { 31 refs.Lock() 32 refs.next = -24 // Go objects get negative reference numbers. Arbitrary starting point. 33 refs.refs = make(map[interface{}]int32) 34 refs.objs = make(map[int32]countedObj) 35 refs.Unlock() 36 } 37 38 // A Ref represents a Java or Go object passed across the language 39 // boundary. 40 type Ref struct { 41 Num int32 42 } 43 44 // Get returns the underlying object. 45 func (r *Ref) Get() interface{} { 46 refs.Lock() 47 o, ok := refs.objs[r.Num] 48 refs.Unlock() 49 if !ok { 50 panic(fmt.Sprintf("unknown ref %d", r.Num)) 51 } 52 return o.obj 53 } 54 55 // Delete decrements the reference count and removes the pinned object 56 // from the object map when the reference count becomes zero. 57 func Delete(num int32) { 58 refs.Lock() 59 defer refs.Unlock() 60 o, ok := refs.objs[num] 61 if !ok { 62 panic(fmt.Sprintf("seq.Delete unknown refnum: %d", num)) 63 } 64 if o.cnt <= 1 { 65 delete(refs.objs, num) 66 delete(refs.refs, o.obj) 67 } else { 68 refs.objs[num] = countedObj{o.obj, o.cnt - 1} 69 } 70 }