From: Martin Vajnar Date: Thu, 25 Jul 2013 12:45:43 +0000 (+0200) Subject: JORTE: switch from deserialize function to endianness callback X-Git-Url: https://rtime.felk.cvut.cz/gitweb/orte.git/commitdiff_plain/fe36c69fd0d022fafc9acf3a51ca1ba780978f35 JORTE: switch from deserialize function to endianness callback Yesterday's attempt at setting the byte order of ByteBuffer through a deserialize function has one significant drawback and that is if more than one data type is defined under one VM instance (thus accessible by other threads) and subscribers are then registered for these data types the deserialize function will stop working correctly, because there are no parameter structures being passed to it, except for the CDR_Codec, thus it had to use a global reference to a byte buffer which is unfortunately overwritten the moment a new data type is registered. If the deserialize function for the previously registered data type is invoked it then tampers with ByteBuffer settings of a newly registered data type. --- diff --git a/orte/include/jorte/jorte_typedefs_defines.h b/orte/include/jorte/jorte_typedefs_defines.h index e6f50fa..37230ca 100644 --- a/orte/include/jorte/jorte_typedefs_defines.h +++ b/orte/include/jorte/jorte_typedefs_defines.h @@ -37,6 +37,14 @@ typedef struct } JORTEDomainEventsContext_t; +typedef struct +{ + JavaVM *jvm; + jobject obj_buf; // byte buffer object + CDR_Endianness cur_endian; +} JORTESetEndiannessContext_t; + + typedef enum { ON_REG_FAIL = 1, ON_MGR_NEW = 2, diff --git a/orte/libjorte/JORTETypeRegisterAdd.c b/orte/libjorte/JORTETypeRegisterAdd.c index f5e6718..d3d2dca 100644 --- a/orte/libjorte/JORTETypeRegisterAdd.c +++ b/orte/libjorte/JORTETypeRegisterAdd.c @@ -25,29 +25,29 @@ * */ +#include #include -#include // library header file's path -#include "orte.h" +#include "orte_all.h" // pregenerated header #include "jorte/org_ocera_orte_DomainApp.h" -#include "jorte/jorte_protos_api.h" -#include "jorte/4all.h" -extern JavaVM *javavm; -static jobject byte_buf; +#include "jorte/jorte_typedefs_defines.h" +#include "jorte/4all.h" -void deserialize(CDR_Codec *cdrCodec, void *instance) { +void set_order(CDR_Codec *cdrCodec, void *param) { JNIEnv *env = 0; jclass cls = 0; jfieldID fid = 0; jmethodID mid = 0; jobject obj_bo = 0; + + JORTESetEndiannessContext_t *ctx = (JORTESetEndiannessContext_t*) param; //set byte order only once - if(byte_buf) { + if(cdrCodec->data_endian != ctx->cur_endian) { // get environment - (*javavm)->AttachCurrentThread(javavm, (void **)&env, NULL); + (*ctx->jvm)->AttachCurrentThread(ctx->jvm, (void **)&env, NULL); if(env == 0) { #ifdef TEST_STAGE @@ -67,12 +67,14 @@ void deserialize(CDR_Codec *cdrCodec, void *instance) { cls, "BIG_ENDIAN", "Ljava/nio/ByteOrder;"); + ctx->cur_endian = BigEndian; } else { fid = (*env)->GetStaticFieldID(env, cls, "LITTLE_ENDIAN", "Ljava/nio/ByteOrder;"); + ctx->cur_endian = LittleEndian; } if(fid == 0) { #ifdef TEST_STAGE @@ -88,7 +90,7 @@ void deserialize(CDR_Codec *cdrCodec, void *instance) { // set byte order to ByteBuffer // get BB class - cls = (*env)->GetObjectClass(env, byte_buf); + cls = (*env)->GetObjectClass(env, ctx->obj_buf); if(cls == 0) { #ifdef TEST_STAGE @@ -108,24 +110,15 @@ void deserialize(CDR_Codec *cdrCodec, void *instance) { } // set ByteOrder - if((*env)->CallObjectMethod(env,byte_buf,mid,obj_bo) == 0) + if((*env)->CallObjectMethod(env,ctx->obj_buf,mid,obj_bo) == 0) { #ifdef TEST_STAGE printf(":!c: set byte order failed.. \n"); #endif } - // delete global reference - (*env)->DeleteGlobalRef(env, byte_buf); - byte_buf = 0; - - (*javavm)->DetachCurrentThread(javavm); + (*ctx->jvm)->DetachCurrentThread(ctx->jvm); } - - //copy over the message instance - memcpy(instance, - cdrCodec->buffer, - cdrCodec->buf_len); } JNIEXPORT jint JNICALL @@ -135,20 +128,46 @@ Java_org_ocera_orte_DomainApp_jORTETypeRegisterAdd const char *name; int b; + JORTESetEndiannessContext_t *ctx = 0; + + jobject byte_buf = 0; + JavaVM *jvm = 0; + + // TODO free() ! + ctx = (JORTESetEndiannessContext_t*) malloc(sizeof(JORTESetEndiannessContext_t)); + if(ctx == 0) { + #ifdef TEST_STAGE + printf(":c!: ctx = NULL\n"); + #endif + } + // create global reference for ByteBuffer + // TODO delete global reference + byte_buf = (*env)->NewGlobalRef(env, obj_bb); + ctx->obj_buf = byte_buf; + // get jvm + b = (*env)->GetJavaVM(env,&jvm); + if (b < 0) + { + printf(":!c: getJavaVM() failed! \n"); + return 0; + } + ctx->jvm = jvm; + ctx->cur_endian = FLAG_ENDIANNESS; + // get type name from JAVA env name = (*env)->GetStringUTFChars(env,jname,0); // call ORTE function b = ORTETypeRegisterAdd((ORTEDomain *) handle, name, NULL, - (ORTETypeDeserialize)deserialize, NULL, - (unsigned int) jlength); + NULL, + (unsigned int) jlength, + (ORTETypeProcessEndianness) set_order, + (void*) ctx); // free memmory space (*env)->ReleaseStringUTFChars(env,jname,name); - byte_buf = (*env)->NewGlobalRef(env, obj_bb); - #ifdef TEST_STAGE printf(":c: jORTETypeRegisterAdd vraci %d [%d = ORTE_OK, %d = ORTE_BAD_HANDLE] \n", b,ORTE_OK,ORTE_BAD_HANDLE); diff --git a/orte/libjorte/onLoad.c b/orte/libjorte/onLoad.c index 21d56b7..f7b8e48 100644 --- a/orte/libjorte/onLoad.c +++ b/orte/libjorte/onLoad.c @@ -5,8 +5,6 @@ static jmethodID findClassM; static jmethodID findLoadedClassM; static jobject classLoader; -JavaVM *javavm; - JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { JNIEnv *env; jclass testCl; @@ -15,7 +13,6 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { jmethodID getClassLoader; (*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_6); - javavm = vm; testCl = (*env)->FindClass(env, "org/ocera/orte/JOrte"); clClass = (*env)->FindClass(env, "java/lang/Class");