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  }