Author: mdonoughe Date: 2006-06-09 10:16:51 -0700 (Fri, 09 Jun 2006) New Revision: 2992
Modified: freeway/native/org_gnu_freeway_server_CPluginLoader.c freeway/native/switch-table.c Log: convObjectToPtr and convPtrToObject now utilize PointerObjects to keep the Java array and the C pointer to it together so the array can be released. More work on serializing and deserializing Java objects of PTR_KIND to C pointers. CWrappers that have variable lengths when serialized should implement static Object newFromPointer(long) and void deserializeFromPointer(long). These methods are not added to the interface because they are only used from C and they are not needed if the serialized size is constant. Also, if the serialized size is constant after creation, only static Object newFromPointer(long) is required. Likewise, void deserializeFromPointer(long) is not necessary if the size is constant after creation. No existing classes implement these functions. Existing code continues to function without it. Modified: freeway/native/org_gnu_freeway_server_CPluginLoader.c =================================================================== --- freeway/native/org_gnu_freeway_server_CPluginLoader.c 2006-06-09 04:14:02 UTC (rev 2991) +++ freeway/native/org_gnu_freeway_server_CPluginLoader.c 2006-06-09 17:16:51 UTC (rev 2992) @@ -52,6 +52,11 @@ struct ModuleList * next; } ModuleList; +typedef struct PointerObject { + void * pointer; + jobject object; +} PointerObject; + /** * FIXME: add proper locking for concurrent access to modules. */ @@ -123,57 +128,94 @@ return (*env)->NewObject(env, classCLong, method, input); } -static void * convObjectToPtr(jobject input, JNIEnv * env) { +static PointerObject * convObjectToPtr(jobject input, JNIEnv * env) { fprintf(stderr, "in convObjectToPtr\n"); jclass objectClass; jmethodID method; - jobject jByteArray; + PointerObject * po; + + po = malloc(sizeof(PointerObject)); + if(po == NULL) + return NULL; if(input == NULL) - return NULL; + return NULL; objectClass = (*env)->GetObjectClass(env, input); if(objectClass == NULL) - return NULL; + return NULL; method = (*env)->GetMethodID(env, objectClass, "serializeToByteArray", "()[B"); if(method == NULL) - return NULL; - jByteArray = (*env)->CallObjectMethod(env, input, method); - void * ret = (*env)->GetByteArrayElements(env, jByteArray, NULL); + return NULL; + po->object = (*env)->CallObjectMethod(env, input, method); + po->pointer = (*env)->GetByteArrayElements(env, po->object, NULL); fprintf(stderr, "leaving convObjectToPtr\n"); - return ret; + return po; } -//FIXME: there is a leak here. array cannot be released -//FIXME: this will not work because we don't know the length of the array + static jobject convPtrToNewObject(void * input, jclass returnType, JNIEnv * env) { -fprintf(stderr, "in convPtrToObject\n"); +fprintf(stderr, "in convPtrToNewObject\n"); jmethodID method; + jmethodID methodSize; + jint size; + jobject object; + jbyteArray array; + int i; - if(input == NULL) - return NULL; + if(input == NULL || returnType == NULL) + return NULL; + method = (*env)->GetStaticMethodID(env, returnType, "newFromPointer", "(J)Ljava/lang/Object;"); + if(method != NULL) + return (*env)->CallStaticObjectMethod(env, returnType, method, input); + (*env)->ExceptionClear(env); + object = (*env)->AllocObject(env, returnType); + if(object == NULL) + return; + methodSize = (*env)->GetMethodID(env, object, "getSerializedSize", "()I"); + if(methodSize == NULL) + return NULL; method = (*env)->GetMethodID(env, returnType, "<init>", "([B)V"); if(method == NULL) - return NULL; -fprintf(stderr, "leaving convPtrToObject\n"); - return (*env)->NewObject(env, input, method); + return NULL; + size = (*env)->CallIntMethod(env, object, methodSize); + array = (*env)->NewByteArray(env, size); + if(array == NULL) + return NULL; + (*env)->SetByteArrayRegion(env, array, 0, size, input); +fprintf(stderr, "leaving convPtrToNewObject\n"); + return (*env)->NewObject(env, returnType, method, array); } -//FIXME:leak, doesn't work, see above -static void updateObjectFromPtr(void * input, jobject target, JNIEnv * env) { -//better to quit while you're ahead here for the sake of testing. This is likely to cause a VM crash. quiting here may be the correct thing to do in most cases. -return; + +static void updateObjectFromPtr(jobject target, PointerObject * input, JNIEnv * env) { fprintf(stderr, "in updateObjectFromPtr\n"); jclass objectClass; jmethodID method; if(input == NULL) return; - objectClass = (*env)->GetObjectClass(env, input); + if(input->pointer == NULL || input->object == NULL) + return; + objectClass = (*env)->GetObjectClass(env, target); if(objectClass == NULL) - return; + return; + method = (*env)->GetMethodID(env, objectClass, "deserializeFromPointer", "(J)V"); + if(method != NULL) { + (*env)->CallVoidMethod(env, target, method, input->pointer); + (*env)->ReleaseByteArrayElements(env, input->object, input->pointer, 0); + free(input); +fprintf(stderr, "leaving updateObjectFromPtr\n"); + return; + } + (*env)->ExceptionClear(env); + (*env)->ReleaseByteArrayElements(env, input->object, input->pointer, 0); method = (*env)->GetMethodID(env, objectClass, "deserializeFromByteArray", "([B)V"); - if(method == NULL) - return; - (*env)->CallVoidMethod(env, target, method, input); + if(method != NULL) { + (*env)->CallVoidMethod(env, target, method, input->object); + free(input); fprintf(stderr, "leaving updateObjectFromPtr\n"); + return; + } + (*env)->ExceptionClear(env); + //Constant CWrappers cannot be updated } static jobject convJStringToCString(jstring input, JNIEnv * env) { @@ -225,7 +267,7 @@ return 0; ret = (*env)->GetLongField(env, retHandle, handle_); fprintf(stderr, "leaving jrequestService: %x\n", ret); - return ret; + return (void *) (long) ret; } static int jloadApplicationModule(const char * name) { Modified: freeway/native/switch-table.c =================================================================== --- freeway/native/switch-table.c 2006-06-09 04:14:02 UTC (rev 2991) +++ freeway/native/switch-table.c 2006-06-09 17:16:51 UTC (rev 2992) @@ -11,8 +11,8 @@ } switch (functionType) { case 13: { - void * carg0 = convObjectToPtr(jargs[0], env); - int cret = ((FunctionType13) ((void**)m->moduleFptrStruct)[functionOffset])(carg0); + PointerObject * carg0 = convObjectToPtr(jargs[0], env); + int cret = ((FunctionType13) ((void**)m->moduleFptrStruct)[functionOffset])(carg0->pointer); updateObjectFromPtr(jargs[0], carg0, env); oret = convIntToCInt(cret, env); break; _______________________________________________ GNUnet-SVN mailing list GNUnet-SVN@gnu.org http://lists.gnu.org/mailman/listinfo/gnunet-svn