From 3d08cdbd6715f28510b9144ea07119cd2ba1635a Mon Sep 17 00:00:00 2001 From: Joe Ferner Date: Fri, 20 Jun 2014 13:48:39 -0400 Subject: [PATCH] add better handling of Proxy lifecycle --- README.md | 4 ++-- compile-java-code.sh | 3 +++ src-java/node/NodeDynamicProxyClass.class | Bin 1132 -> 1144 bytes src-java/node/NodeDynamicProxyClass.java | 14 ++++++-------- src/java.cpp | 9 +++++++++ src/javaObject.cpp | 2 ++ src/node_NodeDynamicProxyClass.h | 8 ++++++++ src/utils.cpp | 2 +- src/utils.h | 1 + 9 files changed, 32 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 1793f88f..df2f2e3b 100644 --- a/README.md +++ b/README.md @@ -384,8 +384,8 @@ __Example__ Creates a new java Proxy for the given interface. Functions passed in will run on the v8 main thread and not a new thread. -The returned object has two methods ref() and unref() which you can use to maintain references to prevent premature -garbage collection. You must call these methods to ensure the proxy stays around. +The returned object has a method unref() which you can use to free the object for +garbage collection. __Arguments__ diff --git a/compile-java-code.sh b/compile-java-code.sh index 2e241b40..bc52d6fe 100755 --- a/compile-java-code.sh +++ b/compile-java-code.sh @@ -8,3 +8,6 @@ javac ${JAVAC_OPTS} *.java cd ../src-java/node javac ${JAVAC_OPTS} *.java + +cd ../../ +javah -classpath src-java -d ./src node.NodeDynamicProxyClass diff --git a/src-java/node/NodeDynamicProxyClass.class b/src-java/node/NodeDynamicProxyClass.class index 90a4f56367d2834056274f2048e0fad964c428f8..9584b6eed16702afa4602f1ccbdcd767ba991816 100644 GIT binary patch delta 437 zcmYjMNlrpR6s-Oq(x0Xo6vP1q98f?M#Sv7L7-K@hmW3{NV&cLB zcm)$r-~o&awR)p0y1MJVs(SrCoKI)__51k+KptfUjd6tuBn?bTOnHz(TET^k!ZflT zcrl|0vj%b!a}x6s`F5!pTo7VHpj1FPV#Xh!q;TD||=LPaNp%*~Q&KDr1mDv#jQF0jBww<42U3 zVBQeBVOT#b*%DESVP;E=nE5fpVKM8?PVAd3MFvjPbpQQ=x-gTdV=oDt9Pnf^k8qx# T?nwmx&2cyscbiA4urT%u;f*cM delta 407 zcmaiuJ5qu{5QM+|0T+H&1VIH6M0|nb3m+&d1_nl?9>6L!vq~+?b5I<_vdjoPfH$$q z0}!dbWJU(lJH0(UJ;V4{yz}urcn6xCg(RtlEVATb*|L&gm0C!YddM2<2|^m7V8gO$ z*|Kc+&Tq|5Z_u^kO*#50bCr3xzA;2<^-DwS=}xTwXd3A(Wy`K(kA24ht^SM2mku3A zv>nHsSWX=sT8?p2jtSClpQdZJ{8JE_W&6HfJ?BkhZ6{g<)A zxOBh4JCpJ_is~xz&q&P?{D?*@c}qc?EVDkT$Q*%o4I`C%zbh0&368>_%#u=+DXpL~ YzFtR-H;s)x{J{MGV^xh+WC~dL1@?R;DgXcg diff --git a/src-java/node/NodeDynamicProxyClass.java b/src-java/node/NodeDynamicProxyClass.java index 56991a8e..223c39ff 100644 --- a/src-java/node/NodeDynamicProxyClass.java +++ b/src-java/node/NodeDynamicProxyClass.java @@ -1,8 +1,10 @@ package node; -public class NodeDynamicProxyClass implements java.lang.reflect.InvocationHandler -{ +import java.util.HashSet; + +public class NodeDynamicProxyClass implements java.lang.reflect.InvocationHandler { private native Object callJs(long ptr, java.lang.reflect.Method m, Object[] args) throws Throwable; + private native void unref(long ptr) throws Throwable; public long ptr; public NodeDynamicProxyClass(String path, long ptr) { @@ -25,11 +27,7 @@ public Object invoke(Object proxy, java.lang.reflect.Method m, Object[] args) th return result; } - public void ref() { - - } - - public void unref() { - + public void unref() throws Throwable { + unref(this.ptr); } } diff --git a/src/java.cpp b/src/java.cpp index e98e0878..ad14bf53 100644 --- a/src/java.cpp +++ b/src/java.cpp @@ -356,6 +356,7 @@ void Java::destroyJVM(JavaVM** jvm, JNIEnv** env) { if(result->IsNativeError()) { return ThrowException(result); } + dynamicProxyData->jsObject = v8::Persistent::New(result); return scope.Close(result); } @@ -989,3 +990,11 @@ JNIEXPORT jobject JNICALL Java_node_NodeDynamicProxyClass_callJs(JNIEnv *env, jo } return dynamicProxyData->result; } + +JNIEXPORT void JNICALL Java_node_NodeDynamicProxyClass_unref(JNIEnv *env, jobject src, jlong ptr) { + DynamicProxyData* dynamicProxyData = (DynamicProxyData*)ptr; + if(!dynamicProxyDataVerify(dynamicProxyData)) { + return; + } + dynamicProxyData->jsObject.Clear(); +} diff --git a/src/javaObject.cpp b/src/javaObject.cpp index dca7036c..e6a0a2ca 100644 --- a/src/javaObject.cpp +++ b/src/javaObject.cpp @@ -97,6 +97,8 @@ JavaObject::~JavaObject() { jfieldID ptrField = env->GetFieldID(nodeDynamicProxyClass, "ptr", "J"); DynamicProxyData* proxyData = (DynamicProxyData*)(long)env->GetLongField(m_obj, ptrField); if(dynamicProxyDataVerify(proxyData)) { + proxyData->markerStart = 0; + proxyData->markerEnd = 0; delete proxyData; } } diff --git a/src/node_NodeDynamicProxyClass.h b/src/node_NodeDynamicProxyClass.h index 3b7b67cf..93b414d2 100644 --- a/src/node_NodeDynamicProxyClass.h +++ b/src/node_NodeDynamicProxyClass.h @@ -15,6 +15,14 @@ extern "C" { JNIEXPORT jobject JNICALL Java_node_NodeDynamicProxyClass_callJs (JNIEnv *, jobject, jlong, jobject, jobjectArray); +/* + * Class: node_NodeDynamicProxyClass + * Method: unref + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_node_NodeDynamicProxyClass_unref + (JNIEnv *, jobject, jlong); + #ifdef __cplusplus } #endif diff --git a/src/utils.cpp b/src/utils.cpp index 13063af7..c9f3015e 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -694,7 +694,7 @@ int dynamicProxyDataVerify(DynamicProxyData* data) { return 1; } - printf("*** ERROR: Lost reference to the dynamic proxy. You must maintain a reference in javascript land using ref() and unref(). ***\n"); + printf("*** ERROR: Lost reference to the dynamic proxy. You must maintain a reference in javascript land using ref() and unref(). (%p) ***\n", data); return 0; } diff --git a/src/utils.h b/src/utils.h index aef6393a..59cdd19f 100644 --- a/src/utils.h +++ b/src/utils.h @@ -35,6 +35,7 @@ struct DynamicProxyData { Java* java; std::string interfaceName; v8::Persistent functions; + v8::Persistent jsObject; std::string methodName; jobjectArray args; jobject result;