peer info with new operations handling
authorSree Harsha Totakura <totakura@in.tum.de>
Wed, 1 Aug 2012 11:12:31 +0000 (11:12 +0000)
committerSree Harsha Totakura <totakura@in.tum.de>
Wed, 1 Aug 2012 11:12:31 +0000 (11:12 +0000)
src/testbed/testbed_api.c
src/testbed/testbed_api.h
src/testbed/testbed_api_peers.c

index 21ade1cea701ce0a464ef4a76013dcb5043dcfda..f8d8e11fc6566d7bd4548cdc28df937ae0b4075e 100644 (file)
@@ -406,7 +406,7 @@ static int
 handle_peer_config (struct GNUNET_TESTBED_Controller *c,
                    const struct GNUNET_TESTBED_PeerConfigurationInformationMessage *msg)
 {
-  struct GNUNET_TESTBED_Operation *op;
+  struct OperationContext *opc;
   struct GNUNET_TESTBED_Peer *peer;
   struct PeerInfoData *data;
   struct PeerInfoData2 *response_data;
@@ -414,32 +414,28 @@ handle_peer_config (struct GNUNET_TESTBED_Controller *c,
   uint64_t op_id;
   
   op_id = GNUNET_ntohll (msg->operation_id);
-  for (op = c->op_head; NULL != op; op = op->next)
-  {
-    if (op->operation_id == op_id)
-      break;
-  }
-  if (NULL == op)
+  if (NULL == (opc = find_opc (c, op_id)))
   {
-    LOG_DEBUG ("Operation not found");
+    LOG_DEBUG ("Operation not found\n");
     return GNUNET_YES;
   }
-  data = op->data;
+  data = opc->data;
   GNUNET_assert (NULL != data);
   peer = data->peer;
   GNUNET_assert (NULL != peer);
   GNUNET_assert (ntohl (msg->peer_id) == peer->unique_id);
+  opc->completed = GNUNET_YES;
   if (0 == (c->event_mask & (1L << GNUNET_TESTBED_ET_OPERATION_FINISHED)))
   {
     LOG_DEBUG ("Skipping operation callback as flag not set\n");
-    GNUNET_CONTAINER_DLL_remove (c->op_head, c->op_tail, op);
     return GNUNET_YES;
   }
   response_data = GNUNET_malloc (sizeof (struct PeerInfoData2));
   response_data->pit = data->pit;
   GNUNET_free (data);
+  opc->data = NULL;
   info.type = GNUNET_TESTBED_ET_OPERATION_FINISHED;
-  info.details.operation_finished.operation = op;
+  info.details.operation_finished.operation = opc->op;
   info.details.operation_finished.op_cls = NULL;
   info.details.operation_finished.emsg = NULL;
   info.details.operation_finished.pit = response_data->pit;
@@ -471,7 +467,7 @@ handle_peer_config (struct GNUNET_TESTBED_Controller *c,
       if (Z_OK != (ret = uncompress ((Bytef *) config, &config_size,
                                     (const Bytef *) &msg[1], (uLong) msize)))
        GNUNET_assert (0);
-      cfg = GNUNET_CONFIGURATION_create ();
+      cfg = GNUNET_CONFIGURATION_create (); /* Freed in oprelease_peer_getinfo */
       GNUNET_assert (GNUNET_OK == 
                     GNUNET_CONFIGURATION_deserialize (cfg, config,
                                                       (size_t) config_size,
@@ -485,8 +481,7 @@ handle_peer_config (struct GNUNET_TESTBED_Controller *c,
     GNUNET_assert (0);         /* never reach here */
     break;
   }
-  op->data = response_data;
-  GNUNET_CONTAINER_DLL_remove (c->op_head, c->op_tail, op);
+  opc->data = response_data;
   c->cc (c->cc_cls, &info);
   return GNUNET_YES;
 }
@@ -1352,28 +1347,9 @@ GNUNET_TESTBED_operation_done (struct GNUNET_TESTBED_Operation *operation)
   case OP_PEER_DESTROY:
   case OP_PEER_START:
   case OP_PEER_STOP:
+  case OP_PEER_INFO:
     GNUNET_TESTBED_operation_release_ (operation);
     return;
-  case OP_PEER_INFO:
-    {
-      struct PeerInfoData2 *data;
-      
-      data = operation->data;
-      switch (data->pit)
-      {
-      case GNUNET_TESTBED_PIT_IDENTITY:
-       GNUNET_free (data->details.peer_identity);
-       break;
-      case GNUNET_TESTBED_PIT_CONFIGURATION:
-       GNUNET_CONFIGURATION_destroy (data->details.cfg);
-       break;
-      case GNUNET_TESTBED_PIT_GENERIC:
-       GNUNET_assert (0);              /* never reach here */
-       break;
-      }
-    }
-    GNUNET_free_non_null (operation->data);
-    break;
   case OP_OVERLAY_CONNECT:
     GNUNET_free_non_null (operation->data);
     break;
index 9d0d8076d5dd35ee68e4e9dbf6c57fce16a7b691..bacb53bb1fa6feae04c0284aff3d1c8356993bd2 100644 (file)
@@ -153,6 +153,11 @@ struct OperationContext
    */
   enum OperationType type;
 
+  /**
+   * Is this operation completed? (has there been a reply from the service)
+   */
+  int completed;
+
 };
 
 
index ca4e46e396d6a8c8c5a03a11476559cec588a543..b30e2a92c4604736a93a62608308017f73e88c16 100644 (file)
@@ -212,6 +212,68 @@ oprelease_peer_stop (void *cls)
 }
 
 
+/**
+ * Function to called when a peer get information operation is ready
+ *
+ * @param cls the closure from GNUNET_TESTBED_operation_create_()
+ */
+static void 
+opstart_peer_getinfo (void *cls)
+{
+  struct OperationContext *opc = cls;
+  struct PeerInfoData *data;  
+  struct GNUNET_TESTBED_PeerGetConfigurationMessage *msg;
+
+  data = opc->data;
+  GNUNET_assert (NULL != data);  
+  msg = GNUNET_malloc (sizeof (struct
+                               GNUNET_TESTBED_PeerGetConfigurationMessage));
+  msg->header.size = htons
+    (sizeof (struct GNUNET_TESTBED_PeerGetConfigurationMessage));
+  msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_GETPEERCONFIG);
+  msg->peer_id = htonl (data->peer->unique_id);
+  msg->operation_id = GNUNET_htonll (opc->id);
+  GNUNET_CONTAINER_DLL_insert_tail (opc->c->ocq_head, opc->c->ocq_tail, opc);
+  GNUNET_TESTBED_queue_message_ (opc->c, &msg->header);
+}
+
+
+/**
+ * Callback which will be called when peer stop type operation is released
+ *
+ * @param cls the closure from GNUNET_TESTBED_operation_create_()
+ */
+static void 
+oprelease_peer_getinfo (void *cls)
+{
+  struct OperationContext *opc = cls;
+  struct PeerInfoData2 *data;
+  
+  if (GNUNET_YES != opc->completed)
+    GNUNET_free_non_null (opc->data);
+  else
+  {
+    data = opc->data;
+    GNUNET_assert (NULL != data);
+    switch (data->pit)
+    {
+    case GNUNET_TESTBED_PIT_CONFIGURATION:
+      GNUNET_CONFIGURATION_destroy (data->details.cfg);
+      break;
+    case GNUNET_TESTBED_PIT_IDENTITY:
+      GNUNET_free (data->details.peer_identity);
+      break;
+    default:
+      GNUNET_assert (0);        /* We should never reach here */
+    }
+    GNUNET_free (data);
+  }
+  GNUNET_CONTAINER_DLL_remove (opc->c->ocq_head, opc->c->ocq_tail, opc);
+  GNUNET_free (opc);
+}
+
+
+
 /**
  * Lookup a peer by ID.
  * 
@@ -398,30 +460,22 @@ struct GNUNET_TESTBED_Operation *
 GNUNET_TESTBED_peer_get_information (struct GNUNET_TESTBED_Peer *peer,
                                     enum GNUNET_TESTBED_PeerInformationType pit)
 {
-  struct GNUNET_TESTBED_PeerGetConfigurationMessage *msg;
-  struct GNUNET_TESTBED_Operation *op;
+  struct OperationContext *opc;
   struct PeerInfoData *data;
-  
+
   GNUNET_assert (GNUNET_TESTBED_PIT_GENERIC != pit);
   data = GNUNET_malloc (sizeof (struct PeerInfoData));
   data->peer = peer;
   data->pit = pit;
-  op = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Operation));
-  op->type = OP_PEER_INFO;
-  op->operation_id = peer->controller->operation_counter++;
-  op->controller = peer->controller;
-  op->data = data;
-  msg = GNUNET_malloc (sizeof (struct
-                               GNUNET_TESTBED_PeerGetConfigurationMessage));
-  msg->header.size = htons
-    (sizeof (struct GNUNET_TESTBED_PeerGetConfigurationMessage));
-  msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_GETPEERCONFIG);
-  msg->peer_id = htonl (peer->unique_id);
-  msg->operation_id = GNUNET_htonll (op->operation_id);
-  GNUNET_CONTAINER_DLL_insert_tail (peer->controller->op_head,
-                                    peer->controller->op_tail, op);
-  GNUNET_TESTBED_queue_message_ (peer->controller, &msg->header);
-  return op;
+  opc = GNUNET_malloc (sizeof (struct OperationContext));
+  opc->c = peer->controller;
+  opc->data = data;
+  opc->type = OP_PEER_INFO;
+  opc->id = opc->c->operation_counter++;
+  opc->op = GNUNET_TESTBED_operation_create_ (opc, &opstart_peer_getinfo,
+                                             &oprelease_peer_getinfo);
+  GNUNET_TESTBED_operation_queue_insert_ (opc->c->opq_peer_create, opc->op);
+  return opc->op;
 }