]> rtime.felk.cvut.cz Git - orte.git/commitdiff
JORTE: fix bug in subscriber callback
authorMartin Vajnar <martin@martin-HP-ProBook-4330s.(none)>
Tue, 8 Apr 2014 08:51:27 +0000 (10:51 +0200)
committerPavel Pisa <pisa@cmp.felk.cvut.cz>
Fri, 19 Sep 2014 20:22:37 +0000 (22:22 +0200)
This fixes a rarely occurring bug in subscriber callback.

When a Java subscriber is being destroyed, during the process
a JORTECallbackContext_t structure, used for storing pointers to Java objects,
was free()'d. If this occurred when new issue had arrived and was being
processed by the receive thread, then the pointer to the, now non-existent,
callback structure would have been dereferenced, leading to a SEGFAULT.

To fix this we now create a pointer to pointer to the specific structure
and pass this pointer to ORTESubcriptionCreate() and use it from the recvCallBack().

orte/libjorte/JORTESubscriptionCreate.c
orte/libjorte/JORTESubscriptionDestroy.c

index b02edea7227c2c06254959bdf8dc73a2d13ce25f..f82d3ea1b65e99971936607b88445f3fa17cbe8b 100644 (file)
@@ -58,7 +58,11 @@ recvCallBack(const ORTERecvInfo *info,void *vinstance, void *recvCallBackParam)
   jmethodID        mid = 0;
   jmethodID        mid_callback = 0;
   //
-  JORTECallbackContext_t   *callback_cont = (JORTECallbackContext_t*)recvCallBackParam;
+  // if the subscriber has been destroyed, return
+  if((*(JORTECallbackContext_t**)recvCallBackParam) == 0)
+    return;
+
+  JORTECallbackContext_t   *callback_cont = *((JORTECallbackContext_t**)recvCallBackParam);
 
   #ifdef TEST_STAGE
     printf("\n\n:c: --------------- recvCallBack called.. --------------- \n");
@@ -352,8 +356,10 @@ Java_org_ocera_orte_Subscription_jORTESubscriptionCreate
   SubscriptionType        stype;
   NtpTime                 deadline;
   NtpTime                 minSeparation;
-  // jorte varialbe
+  // jorte variable
   JORTECallbackContext_t *callback_cont;
+  JORTECallbackContext_t **callback_cont_ptr;
+
   // standart variables
   const char             *topic = 0;
   const char             *typename = 0;
@@ -362,6 +368,8 @@ Java_org_ocera_orte_Subscription_jORTESubscriptionCreate
   // memory alocation
   // don't forget use free() funct.!!
   callback_cont = (JORTECallbackContext_t*)malloc(sizeof(JORTECallbackContext_t));
+  callback_cont_ptr = (JORTECallbackContext_t**)malloc(sizeof(JORTECallbackContext_t*));
+  *callback_cont_ptr = callback_cont;
 
   do
   {
@@ -449,7 +457,7 @@ Java_org_ocera_orte_Subscription_jORTESubscriptionCreate
     (*env)->SetLongField(env,
                         obj,
                         fid,
-                        (jlong) callback_cont);
+                        (jlong) callback_cont_ptr);
     #ifdef TEST_STAGE
        printf(":c: ORTESubscriptionCreate() calling..\n");
     #endif
@@ -479,7 +487,7 @@ Java_org_ocera_orte_Subscription_jORTESubscriptionCreate
                                &deadline,
                                &minSeparation,
                                recvCallBack,
-                               (void*)callback_cont,
+                               (void*)callback_cont_ptr,
                                (uint32_t) j_multicastIP);
     if (s == 0)
     {
index c53653f391e24905d098730eba559ce49a946a72..5d5569ed6f738204ee116979a847ddc67011d1ab 100644 (file)
@@ -94,7 +94,8 @@ Java_org_ocera_orte_Subscription_jORTESubscriptionDestroy
     {
       //JavaVM *jvm;
       //jint ret;
-      JORTECallbackContext_t *ctx = (JORTECallbackContext_t*)h;
+      JORTECallbackContext_t *ctx = *((JORTECallbackContext_t**)h);
+      *((JORTECallbackContext_t**)h) = 0;
       if(ctx->obj)
       {
         #ifdef TEST_STAGE
@@ -124,7 +125,7 @@ Java_org_ocera_orte_Subscription_jORTESubscriptionDestroy
         (*env)->DeleteGlobalRef(env, ctx->obj_buf);
       }
       //
-      free((void*)h);
+      free(ctx);
     }
     // set flag
     flag_ok = 1;