]> rtime.felk.cvut.cz Git - orte.git/commitdiff
JORTE: switch from deserialize function to endianness callback
authorMartin Vajnar <martin.vajnar@gmail.com>
Thu, 25 Jul 2013 12:45:43 +0000 (14:45 +0200)
committerMartin Vajnar <martin.vajnar@gmail.com>
Thu, 25 Jul 2013 12:45:43 +0000 (14:45 +0200)
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.

orte/include/jorte/jorte_typedefs_defines.h
orte/libjorte/JORTETypeRegisterAdd.c
orte/libjorte/onLoad.c

index e6f50fa56c9180f3aacc789c8141365d4fbed8f2..37230ca63f48347a4a7d2aa4bff00d4038f68e4e 100644 (file)
@@ -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,
index f5e6718c2e01c9335ae63e62d4bdf49caa8e258c..d3d2dca7c024b3b68bc9dd1b83cf84d3e372db3f 100644 (file)
   *
   */
 
+#include <stdlib.h>
 #include <jni.h>
-#include <string.h>
 // 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);
index 21d56b7120ca82e9e9f79aca90e286cfa31f850b..f7b8e484e129802156fe0474b482b4f73485d4c5 100644 (file)
@@ -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");