Exemple #1
0
// GoAuthorizer converts the given Java authorizer into a Go authorizer.
func GoAuthorizer(env jutil.Env, jAuth jutil.Object) (security.Authorizer, error) {
	if jAuth.IsNull() {
		return nil, nil
	}
	if jutil.IsInstanceOf(env, jAuth, jPermissionsAuthorizerClass) {
		// Called with our implementation of Authorizer, which maintains a Go reference - use it.
		ref, err := jutil.JLongField(env, jAuth, "nativeRef")
		if err != nil {
			return nil, err
		}
		return *(*security.Authorizer)(jutil.GoRefValue(jutil.Ref(ref))), nil
	}
	// Reference Java dispatcher; it will be de-referenced when the go
	// dispatcher created below is garbage-collected (through the finalizer
	// callback we setup below).
	jAuth = jutil.NewGlobalRef(env, jAuth)
	a := &authorizer{
		jAuth: jAuth,
	}
	runtime.SetFinalizer(a, func(a *authorizer) {
		env, freeFunc := jutil.GetEnv()
		defer freeFunc()
		jutil.DeleteGlobalRef(env, a.jAuth)
	})
	return a, nil
}
Exemple #2
0
//export Java_io_v_impl_google_lib_discovery_UpdateImpl_nativeAttachment
func Java_io_v_impl_google_lib_discovery_UpdateImpl_nativeAttachment(jenv *C.JNIEnv, _ C.jobject, goRef C.jlong, jCtx C.jobject, jName C.jstring, jCbObj C.jobject) {
	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
	ctx, _, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jCtx))))
	if err != nil {
		jutil.JThrowV(env, err)
		return
	}

	update := *(*discovery.Update)(jutil.GoRefValue(jutil.Ref(goRef)))
	name := jutil.GoString(env, jutil.Object(uintptr(unsafe.Pointer(jName))))

	jCb := jutil.Object(uintptr(unsafe.Pointer(jCbObj)))
	jutil.DoAsyncCall(env, jCb, func() (jutil.Object, error) {
		dataOrErr := <-update.Attachment(ctx, name)
		if dataOrErr.Error != nil {
			return jutil.NullObject, err
		}

		env, freeFunc := jutil.GetEnv()
		defer freeFunc()

		jData, err := jutil.JByteArray(env, dataOrErr.Data)
		if err != nil {
			return jutil.NullObject, err
		}
		// Must grab a global reference as we free up the env and all local references that come
		// along with it.
		return jutil.NewGlobalRef(env, jData), nil // Un-refed in DoAsyncCall
	})
}
Exemple #3
0
// GoBlessingStore creates an instance of security.BlessingStore that uses the
// provided Java BlessingStore as its underlying implementation.
func GoBlessingStore(env jutil.Env, jBlessingStore jutil.Object) (security.BlessingStore, error) {
	if jBlessingStore.IsNull() {
		return nil, nil
	}
	if jutil.IsInstanceOf(env, jBlessingStore, jBlessingStoreImplClass) {
		// Called with our implementation of BlessingStore, which maintains a Go reference - use it.
		ref, err := jutil.JLongField(env, jBlessingStore, "nativeRef")
		if err != nil {
			return nil, err
		}
		return (*(*security.BlessingStore)(jutil.GoRefValue(jutil.Ref(ref)))), nil
	}
	// Reference Java BlessingStore; it will be de-referenced when the Go
	// BlessingStore created below is garbage-collected (through the finalizer
	// callback we setup just below).
	jBlessingStore = jutil.NewGlobalRef(env, jBlessingStore)
	s := &blessingStore{
		jBlessingStore: jBlessingStore,
	}
	runtime.SetFinalizer(s, func(s *blessingStore) {
		env, freeFunc := jutil.GetEnv()
		defer freeFunc()
		jutil.DeleteGlobalRef(env, s.jBlessingStore)
	})
	return s, nil
}
Exemple #4
0
func initDriverFactory(env jutil.Env) error {
	jDriverClass, err := jutil.JFindClass(env, "io/v/android/impl/google/discovery/plugins/ble/Driver")
	if err != nil {
		return err
	}
	factory := func(ctx *context.T, _ string) (ble.Driver, error) {
		env, freeFunc := jutil.GetEnv()
		defer freeFunc()

		jCtx, err := jcontext.JavaContext(env, ctx, nil)
		if err != nil {
			return nil, err
		}
		jDriver, err := jutil.NewObject(env, jDriverClass, []jutil.Sign{contextSign}, jCtx)
		if err != nil {
			return nil, err
		}
		// Reference the driver; it will be de-referenced when the driver is garbage-collected.
		jDriver = jutil.NewGlobalRef(env, jDriver)
		d := &driver{jDriver}
		runtime.SetFinalizer(d, func(*driver) {
			env, freeFunc := jutil.GetEnv()
			jutil.DeleteGlobalRef(env, d.jDriver)
			freeFunc()
		})
		return d, nil
	}
	ble.SetDriverFactory(factory)
	return nil
}
Exemple #5
0
// GoPrincipal converts the provided Java VPrincipal object into a Go Principal.
func GoPrincipal(env jutil.Env, jPrincipal jutil.Object) (security.Principal, error) {
	if jPrincipal.IsNull() {
		return nil, nil
	}
	if jutil.IsInstanceOf(env, jPrincipal, jVPrincipalImplClass) {
		// Called with our implementation of VPrincipal, which maintains a Go reference - use it.
		ref, err := jutil.CallLongMethod(env, jPrincipal, "nativeRef", nil)
		if err != nil {
			return nil, err
		}
		return (*(*security.Principal)(jutil.GoRefValue(jutil.Ref(ref)))), nil
	}

	// Reference Java VPrincipal; it will be de-referenced when the Go Principal
	// created below is garbage-collected (through the finalizer callback we
	// setup just below).
	jPrincipal = jutil.NewGlobalRef(env, jPrincipal)
	// Create Go Principal.
	p := &principal{
		jPrincipal: jPrincipal,
	}
	runtime.SetFinalizer(p, func(p *principal) {
		env, freeFunc := jutil.GetEnv()
		defer freeFunc()
		jutil.DeleteGlobalRef(env, p.jPrincipal)
	})
	return p, nil
}
Exemple #6
0
// GoCall creates instance of security.Call that uses the provided Java
// Call as its underlying implementation.
func GoCall(env jutil.Env, jCall jutil.Object) (security.Call, error) {
	if jCall.IsNull() {
		return nil, nil
	}
	if jutil.IsInstanceOf(env, jCall, jCallImplClass) {
		// Called with our implementation of Call, which maintains a Go reference - use it.
		ref, err := jutil.CallLongMethod(env, jCall, "nativeRef", nil)
		if err != nil {
			return nil, err
		}
		return (*(*security.Call)(jutil.GoRefValue(jutil.Ref(ref)))), nil
	}
	// Reference Java call; it will be de-referenced when the go call
	// created below is garbage-collected (through the finalizer callback we
	// setup just below).
	jCall = jutil.NewGlobalRef(env, jCall)
	call := &callImpl{
		jCall: jCall,
	}
	runtime.SetFinalizer(call, func(c *callImpl) {
		env, freeFunc := jutil.GetEnv()
		defer freeFunc()
		jutil.DeleteGlobalRef(env, c.jCall)
	})
	return call, nil
}
Exemple #7
0
//export Java_io_v_impl_google_rpc_StreamImpl_nativeRecv
func Java_io_v_impl_google_rpc_StreamImpl_nativeRecv(jenv *C.JNIEnv, jStream C.jobject, goRef C.jlong, jCallbackObj C.jobject) {
	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
	jCallback := jutil.Object(uintptr(unsafe.Pointer(jCallbackObj)))
	result := new(vdl.Value)
	jutil.DoAsyncCall(env, jCallback, func() (jutil.Object, error) {
		if err := (*(*rpc.Stream)(jutil.GoRefValue(jutil.Ref(goRef)))).Recv(&result); err != nil {
			if err == io.EOF {
				// Java uses EndOfFile error to detect EOF.
				err = verror.NewErrEndOfFile(nil)
			}
			return jutil.NullObject, err
		}
		vomResult, err := vom.Encode(result)
		if err != nil {
			return jutil.NullObject, err
		}
		env, freeFunc := jutil.GetEnv()
		defer freeFunc()
		jResult, err := jutil.JByteArray(env, vomResult)
		if err != nil {
			return jutil.NullObject, err
		}
		// Must grab a global reference as we free up the env and all local references that come along
		// with it.
		return jutil.NewGlobalRef(env, jResult), nil // Un-refed in DoAsyncCall
	})
}
Exemple #8
0
func doFinish(goRef C.jlong, numResults int) (jutil.Object, error) {
	// Have all the results be decoded into *vdl.Value.
	resultPtrs := make([]interface{}, numResults)
	for i := 0; i < numResults; i++ {
		value := new(vdl.Value)
		resultPtrs[i] = &value
	}
	if err := (*(*rpc.ClientCall)(jutil.GoRefValue(jutil.Ref(goRef)))).Finish(resultPtrs...); err != nil {
		// Invocation error.
		return jutil.NullObject, err
	}
	// VOM-encode the results.
	vomResults := make([][]byte, numResults)
	for i, resultPtr := range resultPtrs {
		// Remove the pointer from the result.  Simply *resultPtr doesn't work
		// as resultPtr is of type interface{}.
		result := interface{}(jutil.DerefOrDie(resultPtr))
		var err error
		if vomResults[i], err = vom.Encode(result); err != nil {
			return jutil.NullObject, err
		}
	}
	env, freeFunc := jutil.GetEnv()
	defer freeFunc()
	jArr, err := jutil.JByteArrayArray(env, vomResults)
	if err != nil {
		return jutil.NullObject, err
	}
	// Must grab a global reference as we free up the env and all local references that come along
	// with it.
	return jutil.NewGlobalRef(env, jArr), nil // Un-refed in DoAsyncCall
}
Exemple #9
0
// GoBlessingRoots creates an instance of security.BlessingRoots that uses the
// provided Java BlessingRoots as its underlying implementation.
func GoBlessingRoots(env jutil.Env, jBlessingRoots jutil.Object) (security.BlessingRoots, error) {
	if jBlessingRoots.IsNull() {
		return nil, nil
	}
	if jutil.IsInstanceOf(env, jBlessingRoots, jBlessingRootsImplClass) {
		// Called with our implementation of BlessingRoots, which maintains a Go reference - use it.
		ref, err := jutil.CallLongMethod(env, jBlessingRoots, "nativeRef", nil)
		if err != nil {
			return nil, err
		}
		return (*(*security.BlessingRoots)(jutil.GoRefValue(jutil.Ref(ref)))), nil
	}
	// Reference Java BlessingRoots; it will be de-referenced when the Go
	// BlessingRoots created below is garbage-collected (through the finalizer
	// callback we setup just below).
	jBlessingRoots = jutil.NewGlobalRef(env, jBlessingRoots)
	r := &blessingRoots{
		jBlessingRoots: jBlessingRoots,
	}
	runtime.SetFinalizer(r, func(r *blessingRoots) {
		env, freeFunc := jutil.GetEnv()
		defer freeFunc()
		jutil.DeleteGlobalRef(env, r.jBlessingRoots)
	})
	return r, nil
}
Exemple #10
0
// javaOutputWriter translates an implementation of the Java Vango.OutputWriter interface to Go's io.Writer
func newJavaOutputWriter(env jutil.Env, o jutil.Object) io.Writer {
	ret := &javaOutputWriter{jutil.NewGlobalRef(env, o)}
	runtime.SetFinalizer(ret, func(w *javaOutputWriter) {
		env, freeFunc := jutil.GetEnv()
		defer freeFunc()
		jutil.DeleteGlobalRef(env, w.obj)
	})
	return ret
}
Exemple #11
0
func newListener(env jutil.Env, jListener jutil.Object) flow.Listener {
	// Reference Java Listener; it will be de-referenced when the Go Listener
	// created below is garbage-collected (through the finalizer callback we
	// setup just below).
	jListener = jutil.NewGlobalRef(env, jListener)
	l := &btListener{jListener}
	runtime.SetFinalizer(l, func(l *btListener) {
		env, freeFunc := jutil.GetEnv()
		defer freeFunc()
		jutil.DeleteGlobalRef(env, l.jListener)
	})
	return l
}
Exemple #12
0
//export Java_io_v_v23_syncbase_DatabaseImpl_nativeListenForInvites
func Java_io_v_v23_syncbase_DatabaseImpl_nativeListenForInvites(jenv *C.JNIEnv, jDatabase C.jobject, jContext C.jobject, jInviteHandler C.jobject) {
	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
	database := jutil.Object(uintptr(unsafe.Pointer(jDatabase)))
	handler := jutil.Object(uintptr(unsafe.Pointer(jInviteHandler)))

	ctx, _, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
	if err != nil {
		jutil.JThrowV(env, err)
		return
	}

	jDbId, err := jutil.CallObjectMethod(env, database, "id", nil, idSign)
	if err != nil {
		jutil.JThrowV(env, err)
		return
	}
	dbName, err := jutil.CallStringMethod(env, jDbId, "getName", nil)
	if err != nil {
		jutil.JThrowV(env, err)
		return
	}
	dbBlessing, err := jutil.CallStringMethod(env, jDbId, "getBlessing", nil)
	if err != nil {
		jutil.JThrowV(env, err)
		return
	}

	dbId := wire.Id{Name: dbName, Blessing: dbBlessing}
	// Note: There is no need to use a buffered channel here.  ListenForInvites
	// spawns a goroutine for this listener that acts as an infinite buffer so we can
	// process invites at our own pace.
	ch := make(chan discovery.Invite)
	if err := discovery.ListenForInvites(ctx, dbId, ch); err != nil {
		jutil.JThrowV(env, err)
		return
	}

	handler = jutil.NewGlobalRef(env, handler)
	go func() {
		for invite := range ch {
			if err := handleInvite(invite, handler); err != nil {
				// TODO(mattr): We should cancel the stream and return an error to
				// the user here.
				ctx.Errorf("couldn't call invite handler: %v", err)
			}
		}
		env, free := jutil.GetEnv()
		jutil.DeleteGlobalRef(env, handler)
		free()
	}()
}
Exemple #13
0
// GoAddressChooser converts a Java AddressChooser object into a Go address
// chooser function.
func GoAddressChooser(env jutil.Env, jChooser jutil.Object) rpc.AddressChooser {
	// Reference Java chooser; it will be de-referenced when the go function
	// created below is garbage-collected (through the finalizer callback we
	// setup just below).
	chooser := &jniAddressChooser{
		jChooser: jutil.NewGlobalRef(env, jChooser),
	}
	runtime.SetFinalizer(chooser, func(chooser *jniAddressChooser) {
		env, freeFunc := jutil.GetEnv()
		defer freeFunc()
		jutil.DeleteGlobalRef(env, chooser.jChooser)
	})
	return chooser
}
Exemple #14
0
func (l *btListener) Accept(ctx *context.T) (flow.Conn, error) {
	env, freeFunc := jutil.GetEnv()
	defer freeFunc()

	jStream, err := jutil.CallObjectMethod(env, l.jListener, "accept", nil, streamSign)
	if err != nil {
		return nil, err
	}
	// Reference Java Stream; it will be de-referenced when the Go connection
	// created below is garbage-collected (through the finalizer callback we
	// setup just below).
	jStream = jutil.NewGlobalRef(env, jStream)
	return newConnection(env, jStream), nil
}
Exemple #15
0
// GoContextValue returns the Go Context value given the Java Context value.
func GoContextValue(env jutil.Env, jValue jutil.Object) (interface{}, error) {
	// Reference Java object; it will be de-referenced when the Go wrapper
	// object created below is garbage-collected (via the finalizer we setup
	// just below.)
	jValue = jutil.NewGlobalRef(env, jValue)
	value := &goContextValue{
		jObj: jValue,
	}
	runtime.SetFinalizer(value, func(value *goContextValue) {
		env, freeFunc := jutil.GetEnv()
		defer freeFunc()
		jutil.DeleteGlobalRef(env, value.jObj)
	})
	return value, nil
}
Exemple #16
0
func doResolveToMountTable(n namespace.T, context *context.T, name string, options []naming.NamespaceOpt) (jutil.Object, error) {
	entry, err := n.ResolveToMountTable(context, name, options...)
	if err != nil {
		return jutil.NullObject, err
	}
	env, freeFunc := jutil.GetEnv()
	defer freeFunc()
	jEntry, err := jutil.JVomCopy(env, entry, JMountEntryClass)
	if err != nil {
		return jutil.NullObject, err
	}
	// Must grab a global reference as we free up the env and all local references that come along
	// with it.
	return jutil.NewGlobalRef(env, jEntry), nil // Un-refed in DoAsyncCall
}
Exemple #17
0
func goInvoker(env jutil.Env, jInvoker jutil.Object) (rpc.Invoker, error) {
	// Reference Java invoker; it will be de-referenced when the go invoker
	// created below is garbage-collected (through the finalizer callback we
	// setup just below).
	jInvoker = jutil.NewGlobalRef(env, jInvoker)
	i := &invoker{
		jInvoker: jInvoker,
	}
	runtime.SetFinalizer(i, func(i *invoker) {
		env, freeFunc := jutil.GetEnv()
		defer freeFunc()
		jutil.DeleteGlobalRef(env, i.jInvoker)
	})
	return i, nil
}
Exemple #18
0
// GoSigner creates an instance of security.Signer that uses the provided
// Java VSigner as its underlying implementation.
func GoSigner(env jutil.Env, jSigner jutil.Object) (security.Signer, error) {
	// Reference Java VSigner; it will be de-referenced when the Go Signer
	// created below is garbage-collected (through the finalizer callback we
	// setup just below).
	jSigner = jutil.NewGlobalRef(env, jSigner)
	s := &signer{
		jSigner: jSigner,
	}
	runtime.SetFinalizer(s, func(s *signer) {
		env, freeFunc := jutil.GetEnv()
		defer freeFunc()
		jutil.DeleteGlobalRef(env, s.jSigner)
	})
	return s, nil
}
Exemple #19
0
// GoDispatcher creates a new rpc.Dispatcher given the Java Dispatcher object.
func GoDispatcher(env jutil.Env, jDispatcher jutil.Object) (rpc.Dispatcher, error) {
	// Reference Java dispatcher; it will be de-referenced when the go
	// dispatcher created below is garbage-collected (through the finalizer
	// callback we setup below).
	jDispatcher = jutil.NewGlobalRef(env, jDispatcher)
	d := &dispatcher{
		jDispatcher: jDispatcher,
	}
	runtime.SetFinalizer(d, func(d *dispatcher) {
		env, freeFunc := jutil.GetEnv()
		defer freeFunc()
		jutil.DeleteGlobalRef(env, d.jDispatcher)
	})

	return d, nil
}
Exemple #20
0
func (btProtocol) Dial(ctx *context.T, protocol, address string, timeout time.Duration) (flow.Conn, error) {
	env, freeFunc := jutil.GetEnv()
	defer freeFunc()

	jContext, err := jcontext.JavaContext(env, ctx, nil)
	if err != nil {
		return nil, err
	}
	jStream, err := jutil.CallStaticObjectMethod(env, jBluetoothClass, "dial", []jutil.Sign{contextSign, jutil.StringSign, jutil.DurationSign}, streamSign, jContext, address, timeout)
	if err != nil {
		return nil, err
	}
	// Reference Java Stream; it will be de-referenced when the Go connection
	// created below is garbage-collected (through the finalizer callback we
	// setup just below).
	jStream = jutil.NewGlobalRef(env, jStream)
	return newConnection(env, jStream), nil
}
Exemple #21
0
func doStartCall(context *context.T, cancel func(), name, method string, opts []rpc.CallOpt, goRef C.jlong, args []interface{}) (jutil.Object, error) {
	// Invoke StartCall
	call, err := (*(*rpc.Client)(jutil.GoRefValue(jutil.Ref(goRef)))).StartCall(context, name, method, args, opts...)
	if err != nil {
		return jutil.NullObject, err
	}
	env, freeFunc := jutil.GetEnv()
	defer freeFunc()
	jContext, err := jcontext.JavaContext(env, context, cancel)
	if err != nil {
		return jutil.NullObject, err
	}
	jCall, err := javaCall(env, jContext, call)
	if err != nil {
		return jutil.NullObject, err
	}
	// Must grab a global reference as we free up the env and all local references that come along
	// with it.
	return jutil.NewGlobalRef(env, jCall), nil // Un-refed in DoAsyncCall
}
Exemple #22
0
//export Java_io_v_impl_google_namespace_NamespaceImpl_nativeGlob
func Java_io_v_impl_google_namespace_NamespaceImpl_nativeGlob(jenv *C.JNIEnv, jNamespaceClass C.jclass, goRef C.jlong, jContext C.jobject, jPattern C.jstring, jOptions C.jobject) C.jobject {
	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
	n := *(*namespace.T)(jutil.GoRefValue(jutil.Ref(goRef)))
	ctx, cancel, pattern, opts, err := globArgs(env, jContext, jPattern, jOptions)
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	var globChannel <-chan naming.GlobReply
	var globError error
	globDone := make(chan bool)
	go func() {
		globChannel, globError = n.Glob(ctx, pattern, opts...)
		close(globDone)
	}()
	jChannel, err := jchannel.JavaInputChannel(env, ctx, cancel, func() (jutil.Object, error) {
		// A few blocking calls below - don't call GetEnv() before they complete.
		<-globDone
		if globError != nil {
			return jutil.NullObject, globError
		}
		globReply, ok := <-globChannel
		if !ok {
			return jutil.NullObject, verror.NewErrEndOfFile(ctx)
		}
		env, freeFunc := jutil.GetEnv()
		defer freeFunc()
		jReply, err := jutil.JVomCopy(env, globReply, jGlobReplyClass)
		if err != nil {
			return jutil.NullObject, err
		}
		// Must grab a global reference as we free up the env and all local references that come
		// along with it.
		return jutil.NewGlobalRef(env, jReply), nil // Un-refed by InputChannelImpl_nativeRecv
	})
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	return C.jobject(unsafe.Pointer(jChannel))
}
Exemple #23
0
func doGetPermissions(n namespace.T, context *context.T, name string, options []naming.NamespaceOpt) (jutil.Object, error) {
	permissions, version, err := n.GetPermissions(context, name, options...)
	if err != nil {
		return jutil.NullObject, err
	}
	env, freeFunc := jutil.GetEnv()
	defer freeFunc()
	jPermissions, err := jutil.JVomCopy(env, permissions, jPermissionsClass)
	if err != nil {
		return jutil.NullObject, err
	}
	result := make(map[jutil.Object]jutil.Object)
	result[jutil.JString(env, version)] = jPermissions
	jResult, err := jutil.JObjectMap(env, result)
	if err != nil {
		return jutil.NullObject, err
	}
	// Must grab a global reference as we free up the env and all local references that come along
	// with it.
	return jutil.NewGlobalRef(env, jResult), nil // Un-refed in DoAsyncCall
}
Exemple #24
0
//export Java_io_v_impl_google_lib_discovery_DiscoveryImpl_nativeScan
func Java_io_v_impl_google_lib_discovery_DiscoveryImpl_nativeScan(jenv *C.JNIEnv, _ C.jobject, goRef C.jlong, jCtx C.jobject, jQuery C.jstring) C.jobject {
	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
	ctx, _, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jCtx))))
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}

	d := *(*discovery.T)(jutil.GoRefValue(jutil.Ref(goRef)))
	query := jutil.GoString(env, jutil.Object(uintptr(unsafe.Pointer(jQuery))))

	scanCh, err := d.Scan(ctx, query)
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}

	jChannel, err := jchannel.JavaInputChannel(env, ctx, nil, func() (jutil.Object, error) {
		update, ok := <-scanCh
		if !ok {
			return jutil.NullObject, verror.NewErrEndOfFile(ctx)
		}

		env, freeFunc := jutil.GetEnv()
		defer freeFunc()

		jUpdate, err := javaUpdate(env, update)
		if err != nil {
			return jutil.NullObject, err
		}
		// Must grab a global reference as we free up the env and all local references that come
		// along with it.
		return jutil.NewGlobalRef(env, jUpdate), nil // un-refed by InputChannelImpl_nativeRecv
	})
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	return C.jobject(unsafe.Pointer(jChannel))
}
Exemple #25
0
//export Java_io_v_v23_context_VContext_nativeOnDone
func Java_io_v_v23_context_VContext_nativeOnDone(jenv *C.JNIEnv, jVContext C.jobject, goRef C.jlong, jCallbackObj C.jobject) {
	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
	jCallback := jutil.Object(uintptr(unsafe.Pointer(jCallbackObj)))
	ctx := (*(*context.T)(jutil.GoRefValue(jutil.Ref(goRef))))
	c := ctx.Done()
	if c == nil {
		jutil.CallbackOnFailure(env, jCallback, errors.New("Context isn't cancelable"))
		return
	}
	jutil.DoAsyncCall(env, jCallback, func() (jutil.Object, error) {
		<-c
		env, freeFunc := jutil.GetEnv()
		defer freeFunc()
		jReason, err := JavaContextDoneReason(env, ctx.Err())
		if err != nil {
			return jutil.NullObject, err
		}
		// Must grab a global reference as we free up the env and all local references that come along
		// with it.
		return jutil.NewGlobalRef(env, jReason), nil // Un-refed in DoAsyncCall
	})
}
Exemple #26
0
//export Java_io_v_impl_google_rpc_ClientImpl_nativeStartCall
func Java_io_v_impl_google_rpc_ClientImpl_nativeStartCall(jenv *C.JNIEnv, jClientObj C.jobject, goRef C.jlong,
	jContext C.jobject, jName C.jstring, jMethod C.jstring, jVomArgs C.jobjectArray, jOptionsObj C.jobject, jCallbackObj C.jobject) {
	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
	name := jutil.GoString(env, jutil.Object(uintptr(unsafe.Pointer(jName))))
	method := jutil.GoString(env, jutil.Object(uintptr(unsafe.Pointer(jMethod))))
	jOptions := jutil.Object(uintptr(unsafe.Pointer(jOptionsObj)))
	jCallback := jutil.Object(uintptr(unsafe.Pointer(jCallbackObj)))
	ctx, cancel, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
	if err != nil {
		jutil.CallbackOnFailure(env, jCallback, err)
		return
	}
	args, err := decodeArgs(env, jVomArgs)
	if err != nil {
		jutil.CallbackOnFailure(env, jCallback, err)
		return
	}

	opts, err := jopts.GoRpcOpts(env, jOptions)
	if err != nil {
		jutil.CallbackOnFailure(env, jCallback, err)
		return
	}

	// Create a global reference to the client object for the duration of the call
	// so that the java object doesn't get garbage collected while the async call
	// is happening. This is an issue because if the java object is garbage collected,
	// the go ref will also be collected causing doStartCall to panic.
	jClient := jutil.NewGlobalRef(env, jutil.Object(uintptr(unsafe.Pointer(jClientObj))))
	jutil.DoAsyncCall(env, jCallback, func() (jutil.Object, error) {
		obj, err := doStartCall(ctx, cancel, name, method, opts, goRef, args)
		env, freeFunc := jutil.GetEnv()
		jutil.DeleteGlobalRef(env, jClient)
		freeFunc()
		return obj, err
	})
}