Added helper for cleaning up jni-side references for callbacks.
authorMichael Zucchi <michael@swordfish.com.au>
Sun, 12 May 2019 08:00:05 +0000 (17:30 +0930)
committerMichael Zucchi <michael@swordfish.com.au>
Sun, 12 May 2019 08:00:05 +0000 (17:30 +0930)
This means the library is also now loaded by jni.

src/notzed.nativez/classes/au/notzed/nativez/NativeZ.java
src/notzed.nativez/classes/au/notzed/nativez/ReferenceZ.java [new file with mode: 0644]
src/notzed.nativez/jni/nativez-jni.c
src/notzed.nativez/jni/nativez-jni.def
src/notzed.nativez/jni/nativez.h

index f33ce74..19d3ae1 100644 (file)
@@ -72,6 +72,8 @@ public abstract class NativeZ {
        static private final ReferenceQueue<NativeZ> references = new ReferenceQueue<>();
 
        static {
+               System.loadLibrary("nativez");
+
                Thread cleanup = new Thread(NativeZ::cleaner, "NativeZ cleaner");
                cleanup.setPriority(Thread.MAX_PRIORITY);
                cleanup.setDaemon(true);
diff --git a/src/notzed.nativez/classes/au/notzed/nativez/ReferenceZ.java b/src/notzed.nativez/classes/au/notzed/nativez/ReferenceZ.java
new file mode 100644 (file)
index 0000000..c80bc29
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2019 Michael Zucchi
+ *
+ * This file is part of nativez <https://www.zedzone.space/software/nativez.html>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     (1) Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer. 
+ *
+ *     (2) Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.  
+ *     
+ *     (3)The name of the author may not be used to
+ *     endorse or promote products derived from this software without
+ *     specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE. 
+ * 
+ */
+package au.notzed.nativez;
+
+/**
+ * This is a native object which keeps references to Java objects.
+ * <p>
+ * This is used when a native object requires some references but has
+ * nowhere in the native object being wrapped to store them.
+ * <p>
+ * This is only used by the native code side.
+ */
+public class ReferenceZ extends NativeZ {
+
+       public ReferenceZ(long p) {
+               super(p);
+       }
+
+       private static native void release(long p);
+
+}
index 77c553c..a3dfaf4 100644 (file)
@@ -52,7 +52,23 @@ static int fail(const char *ctx, const char *what) {
        return -1;
 }
 
+jint JNI_OnLoad(JavaVM *vmi, void *reserved) {
+       JNIEnv *env;
+       
+       if ((*vmi)->GetEnv(vmi, (void *)&env, JNI_VERSION_1_4) < 0)
+               return 0;
+
+       if (nativez_OnLoad(vmi, env) != 0)
+               return 0;
+
+       
+       return JNI_VERSION_1_4;
+}
+
 jint nativez_OnLoad(JavaVM *vmi, JNIEnv *env) {
+       /* Only init once */
+       if (vm)
+               return 0;
        /* Save VM - required for callbacks from threads */
        vm = vmi;
 
@@ -366,3 +382,25 @@ void *NativeZ_getP(JNIEnv *env, jobject jo) {
        else
                return NULL;
 }
+
+#include "au_notzed_nativez_ReferenceZ.h"
+
+typedef struct NZReferenceZ {
+       size_t count;
+       jobject jreference[];
+} NZReferenceZ;
+
+jobject ReferenceZ_create(JNIEnv *env, jobject *reflist, size_t count) {
+       NZReferenceZ *ref = malloc(sizeof(*ref) + sizeof(jobject) * count);
+
+       if (!ref) {
+               nativez_ThrowOutOfMemoryError(env, "Creating ReferenceZ");
+               return NULL;
+       }
+
+       ref->count = count;
+       for (int i=0;i<count;i++)
+               ref->jreference[i] = (*env)->NewGlobalRef(env, reflist[i]);
+
+       return NativeZ_create(env, ReferenceZ_classid, ref);
+}
index 3fa29af..f85b4a2 100644 (file)
@@ -20,3 +20,7 @@ java NativeZ au/notzed/nativez/NativeZ {
      static refer, (Ljava/lang/Class;J)Lau/notzed/nativez/NativeZ;
      p, J
 }
+
+java ReferenceZ au/notzed/nativez/ReferenceZ {
+}
+
index a192dbb..2258408 100644 (file)
@@ -86,8 +86,8 @@ int nativez_ResolveFunctions(JNIEnv *env, const NZLibTable *table, const char *f
 #define NZCALL(x) (fn.x)
 
 /**
- * Checks if ptr is non-null, if it is null throws a NullPointer
- * exception with the given description and returns true.
+ * Checks if ptr is non-null.  If it is null throws a NullPointer
+ * exception with the given description and returns false.
  */
 int nativez_NonNull(JNIEnv *env, const char *what, void *ptr);
 
@@ -200,4 +200,7 @@ jobject NativeZ_refer(JNIEnv *env, jclass jc, void *p);
 /* Retreive the native pointer stored in NativeZ subclass instance jo */
 void *NativeZ_getP(JNIEnv *env, jobject jo);
 
+/* Create an object which maintains jni-side references to java objects */
+jobject ReferenceZ_create(JNIEnv *env, jobject *reflist, size_t count);
+
 #endif