peer create callback
authorSree Harsha Totakura <totakura@in.tum.de>
Fri, 20 Jul 2012 12:02:27 +0000 (12:02 +0000)
committerSree Harsha Totakura <totakura@in.tum.de>
Fri, 20 Jul 2012 12:02:27 +0000 (12:02 +0000)
src/include/gnunet_testbed_service.h
src/testbed/gnunet-service-testbed.c
src/testbed/test_testbed_api.c
src/testbed/test_testbed_api_2peers.c
src/testbed/testbed.h
src/testbed/testbed_api.c
src/testbed/testbed_api.h
src/testbed/testbed_api_peers.c
src/testbed/testbed_api_peers.h

index d6c4354feccad3dd70fa32460115fcc548235eed..19928623fb1b4c92a337ea105a9a79c30a8cbfed 100644 (file)
@@ -612,7 +612,21 @@ GNUNET_TESTBED_controller_link_2 (struct GNUNET_TESTBED_Controller *master,
                                  const char *sxcfg,
                                  size_t sxcfg_size,
                                  size_t scfg_size,
-                                 int is_subordinate); 
+                                 int is_subordinate);
+
+
+/**
+ * Functions of this signature are called when a peer has been successfully
+ * created
+ *
+ * @param cls the closure from GNUNET_TESTBED_peer_create()
+ * @param peer the handle for the created peer; NULL on any error during
+ *          creation
+ * @param emsg NULL if peer is not NULL; else MAY contain the error description
+ */
+typedef void (*GNUNET_TESTBED_PeerCreateCallback) (void *cls,
+                                                  struct GNUNET_TESTBED_Peer *peer,
+                                                  const char *emsg);
 
 
 /**
@@ -639,12 +653,16 @@ GNUNET_TESTBED_controller_link_2 (struct GNUNET_TESTBED_Controller *master,
  * @param controller controller process to use
  * @param host host to run the peer on
  * @param cfg configuration to use for the peer
- * @return handle to the peer (actual startup will happen asynchronously)
+ * @param cb the callback to call when the peer has been created
+ * @param cls the closure to the above callback
+ * @return the operation handle
  */
-struct GNUNET_TESTBED_Peer *
+struct GNUNET_TESTBED_Operation *
 GNUNET_TESTBED_peer_create (struct GNUNET_TESTBED_Controller *controller,
                            struct GNUNET_TESTBED_Host *host,
-                           const struct GNUNET_CONFIGURATION_Handle *cfg);
+                           const struct GNUNET_CONFIGURATION_Handle *cfg,
+                           GNUNET_TESTBED_PeerCreateCallback cb,
+                           void *cls);
 
 
 /**
index ef4a5838f24d70f3075e1817d0ae9fd92bfc6152..b0fb722289b311bb4e0c515654d9b968f510bc05 100644 (file)
@@ -1157,6 +1157,7 @@ handle_peer_create (void *cls,
                     const struct GNUNET_MessageHeader *message)
 {
   const struct GNUNET_TESTBED_PeerCreateMessage *msg;
+  struct GNUNET_TESTBED_PeerCreateSuccessEventMessage *reply;
   struct GNUNET_CONFIGURATION_Handle *cfg;
   char *config;
   size_t dest_size;
@@ -1224,6 +1225,12 @@ handle_peer_create (void *cls,
       return;
     }
     peer_list_add (peer);
+    reply = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_PeerCreateSuccessEventMessage));
+    reply->header.size = htons (sizeof (struct GNUNET_TESTBED_PeerCreateSuccessEventMessage));
+    reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEERCREATESUCCESS);
+    reply->peer_id = msg->peer_id;
+    reply->operation_id = msg->operation_id;
+    queue_message (client, &reply->header);
     GNUNET_SERVER_receive_done (client, GNUNET_OK);
     return;
   }
@@ -1284,6 +1291,7 @@ handle_peer_destroy (void *cls,
   reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_GENERICOPSUCCESS);
   reply->header.size = htons (reply_size);
   reply->operation_id = msg->operation_id;
+  reply->event_type = htonl (GNUNET_TESTBED_ET_OPERATION_FINISHED);
   queue_message (client, &reply->header);
   GNUNET_SERVER_receive_done (client, GNUNET_OK);
 }
@@ -1302,7 +1310,7 @@ handle_peer_start (void *cls,
                   const struct GNUNET_MessageHeader *message)
 {
   const struct GNUNET_TESTBED_PeerStartMessage *msg;
-  struct GNUNET_TESTBED_PeerCreateSuccessEventMessage *reply;
+  struct GNUNET_TESTBED_PeerEventMessage *reply;
   uint32_t peer_id;
 
   msg = (const struct GNUNET_TESTBED_PeerStartMessage *) message;
@@ -1316,10 +1324,19 @@ handle_peer_start (void *cls,
     GNUNET_SERVER_receive_done (client, GNUNET_OK);
     return;
   }
-  reply = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_PeerCreateSuccessEventMessage));
-  reply->header.size = htons (sizeof (struct GNUNET_TESTBED_PeerCreateSuccessEventMessage));
-  reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEERCREATESUCCESS);
-  reply->peer_id = htonl (peer_id);
+  if (GNUNET_OK != GNUNET_TESTING_peer_start (peer_list[peer_id]->peer))
+  {
+    /* FIXME: return FAILURE message */
+    GNUNET_break (0);
+    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    return;
+  }
+  reply = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_PeerEventMessage));
+  reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEEREVENT);
+  reply->header.size = htons (sizeof (struct GNUNET_TESTBED_PeerEventMessage));
+  reply->event_type = htonl (GNUNET_TESTBED_ET_PEER_START);
+  reply->host_id = htonl (master_context->host_id);
+  reply->peer_id = msg->peer_id;
   reply->operation_id = msg->operation_id;
   queue_message (client, &reply->header);
   GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -1339,7 +1356,7 @@ handle_peer_stop (void *cls,
                  const struct GNUNET_MessageHeader *message)
 {
   const struct GNUNET_TESTBED_PeerStopMessage *msg;
-  struct GNUNET_TESTBED_GenericOperationSuccessEventMessage *reply;
+  struct GNUNET_TESTBED_PeerEventMessage *reply;
   uint32_t peer_id;
 
   msg = (const struct GNUNET_TESTBED_PeerStopMessage *) message;
@@ -1357,11 +1374,13 @@ handle_peer_stop (void *cls,
     GNUNET_SERVER_receive_done (client, GNUNET_OK);
     return;
   }
-  reply = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_GenericOperationSuccessEventMessage));
-  reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_GENERICOPSUCCESS);
-  reply->header.size = htons (sizeof (struct GNUNET_TESTBED_GenericOperationSuccessEventMessage));
-  reply->operation_id = msg->operation_id;
+  reply = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_PeerEventMessage));
+  reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEEREVENT);
+  reply->header.size = htons (sizeof (struct GNUNET_TESTBED_PeerEventMessage));
   reply->event_type = htonl (GNUNET_TESTBED_ET_PEER_STOP);
+  reply->host_id = htonl (master_context->host_id);
+  reply->peer_id = msg->peer_id;
+  reply->operation_id = msg->operation_id;
   queue_message (client, &reply->header);
   GNUNET_SERVER_receive_done (client, GNUNET_OK);
 }
index 6378fd9cc288b2d07a29c9959857edd3cef317f5..3ae6dbd678b2904019da4af5181504124adeb8a4 100644 (file)
@@ -152,6 +152,30 @@ controller_cb(void *cls, const struct GNUNET_TESTBED_EventInformation *event)
 }
 
 
+/**
+ * Functions of this signature are called when a peer has been successfully
+ * created
+ *
+ * @param cls the closure from GNUNET_TESTBED_peer_create()
+ * @param peer the handle for the created peer; NULL on any error during
+ *          creation
+ * @param emsg NULL if peer is not NULL; else MAY contain the error description
+ */
+static void
+peer_create_cb (void *cls,
+               struct GNUNET_TESTBED_Peer *peer, const char *emsg)
+{
+  struct GNUNET_TESTBED_Peer **peer_ptr;
+  
+  peer_ptr = cls;
+  GNUNET_assert (NULL != peer);
+  GNUNET_assert (NULL != peer_ptr);
+  *peer_ptr = peer;
+  operation = GNUNET_TESTBED_peer_destroy (peer);
+  GNUNET_assert (NULL != operation);
+}
+
+
 /**
  * Callback which will be called to after a host registration succeeded or failed
  *
@@ -163,9 +187,7 @@ registration_comp (void *cls, const char *emsg)
 {
   GNUNET_assert (cls == neighbour);
   reg_handle = NULL;  
-  peer = GNUNET_TESTBED_peer_create (controller, host, cfg);
-  GNUNET_assert (NULL != peer);
-  operation = GNUNET_TESTBED_peer_destroy (peer);
+  operation = GNUNET_TESTBED_peer_create (controller, host, cfg, &peer_create_cb, &peer);
   GNUNET_assert (NULL != operation);
 }
 
index 9f55b61eb3e8145030e631510ad0200711fadbb3..c8422ba9d0a22ca3a14b8a7f6d65b4b9e0acc17f 100644 (file)
@@ -153,6 +153,30 @@ controller_cb(void *cls, const struct GNUNET_TESTBED_EventInformation *event)
 }
 
 
+/**
+ * Functions of this signature are called when a peer has been successfully
+ * created
+ *
+ * @param cls the closure from GNUNET_TESTBED_peer_create()
+ * @param peer the handle for the created peer; NULL on any error during
+ *          creation
+ * @param emsg NULL if peer is not NULL; else MAY contain the error description
+ */
+static void
+peer_create_cb (void *cls,
+               struct GNUNET_TESTBED_Peer *peer, const char *emsg)
+{
+  struct GNUNET_TESTBED_Peer **peer_ptr;
+  
+  peer_ptr = cls;
+  GNUNET_assert (NULL != peer);
+  GNUNET_assert (NULL != peer_ptr);
+  *peer_ptr = peer;
+  operation = GNUNET_TESTBED_peer_destroy (peer);
+  GNUNET_assert (NULL != operation);
+}
+
+
 /**
  * Callback which will be called to after a host registration succeeded or failed
  *
@@ -164,9 +188,7 @@ registration_comp (void *cls, const char *emsg)
 {
   GNUNET_assert (cls == neighbour);
   reg_handle = NULL;  
-  peer = GNUNET_TESTBED_peer_create (controller, host, cfg);
-  GNUNET_assert (NULL != peer);
-  operation = GNUNET_TESTBED_peer_destroy (peer);
+  operation = GNUNET_TESTBED_peer_create (controller, host, cfg, &peer_create_cb, &peer);
   GNUNET_assert (NULL != operation);
 }
 
index fff76f2ec472673807b52b066b00a9bc3eab6e9c..a2bb77e3dc9540cbea8750e2d2bb029e8c423d11 100644 (file)
@@ -197,6 +197,11 @@ struct GNUNET_TESTBED_PeerCreateMessage
    */
   struct GNUNET_MessageHeader header;
 
+  /**
+   * Unique operation id
+   */
+  uint64_t operation_id GNUNET_PACKED;
+
   /**
    * On which host should the peer be started?
    */
index e343daa31108d01c503ffa97e8719a4d70bfbab7..f7d58e9bb2116b2143269fc5433b5507d29cb477 100644 (file)
@@ -300,7 +300,10 @@ handle_peer_create_success (struct GNUNET_TESTBED_Controller *c,
                            GNUNET_TESTBED_PeerCreateSuccessEventMessage *msg)
 {
   struct GNUNET_TESTBED_Operation *op;
+  struct PeerCreateData *data;
   struct GNUNET_TESTBED_Peer *peer;
+  GNUNET_TESTBED_PeerCreateCallback cb;
+  void *cls;
   uint64_t op_id;
 
   GNUNET_assert (sizeof (struct GNUNET_TESTBED_PeerCreateSuccessEventMessage)
@@ -311,21 +314,24 @@ handle_peer_create_success (struct GNUNET_TESTBED_Controller *c,
     if (op->operation_id == op_id)
       break;
   }
-  GNUNET_assert (NULL != op);
-  peer = op->data;
-  GNUNET_assert (NULL != peer);
-  GNUNET_assert (peer->unique_id == ntohl (msg->peer_id));
-  if (0 != (c->event_mask & (1L << GNUNET_TESTBED_ET_PEER_START)))
+  if (NULL == op)
   {
-    struct GNUNET_TESTBED_EventInformation info;
-    
-    info.details.peer_start.host = peer->host;
-    info.details.peer_start.peer = peer;
-    if (NULL != c->cc)
-      c->cc (c->cc_cls, &info);
+    LOG_DEBUG ("Operation not found\n");
+    return GNUNET_YES;
   }
+  GNUNET_assert (OP_PEER_CREATE == op->type);
+  GNUNET_assert (NULL != op->data);
+  data = op->data;
+  GNUNET_assert (NULL != data->peer);
+  peer = data->peer;
+  GNUNET_assert (peer->unique_id == ntohl (msg->peer_id));
+  cb = data->cb;
+  cls = data->cls;
   GNUNET_CONTAINER_DLL_remove (c->op_head, c->op_tail, op);
+  GNUNET_free (data);
   GNUNET_free (op);
+  if (NULL != cb)
+    cb (cls, peer, NULL);
   return GNUNET_YES;
 }
 
index a01ea1c29df476414a3dda8f3e8e5c4ec7ebfeb6..e83e21b52460b816c057020a986fc28d8f9ab1b3 100644 (file)
  */
 enum OperationType
   {
+    /**
+     * Peer create operation
+     */
+    OP_PEER_CREATE,
+    
     /**
      * Peer start operation
      */
index 8beae14f91bb1177c49cde460d5109ff9fbd13ef..0010105dc384101a5f14275bb053442b50bc0b8e 100644 (file)
@@ -72,15 +72,21 @@ GNUNET_TESTBED_peer_lookup_by_id_ (uint32_t id)
  * @param controller controller process to use
  * @param host host to run the peer on
  * @param cfg configuration to use for the peer
- * @return handle to the peer (actual startup will happen asynchronously)
+ * @param cb the callback to call when the peer has been created
+ * @param cls the closure to the above callback
+ * @return the operation handle
  */
-struct GNUNET_TESTBED_Peer *
+struct GNUNET_TESTBED_Operation *
 GNUNET_TESTBED_peer_create_with_id_ (uint32_t unique_id,
                                     struct GNUNET_TESTBED_Controller *controller,
                                     struct GNUNET_TESTBED_Host *host,
-                                    const struct GNUNET_CONFIGURATION_Handle *cfg)
+                                    const struct GNUNET_CONFIGURATION_Handle *cfg,
+                                    GNUNET_TESTBED_PeerCreateCallback cb,
+                                    void *cls)
 {
   struct GNUNET_TESTBED_Peer *peer;
+  struct PeerCreateData *data;
+  struct GNUNET_TESTBED_Operation *op;
   struct GNUNET_TESTBED_PeerCreateMessage *msg;
   char *config;
   char *xconfig;
@@ -92,6 +98,14 @@ GNUNET_TESTBED_peer_create_with_id_ (uint32_t unique_id,
   peer->controller = controller;
   peer->host = host;
   peer->unique_id = unique_id;
+  data = GNUNET_malloc (sizeof (struct PeerCreateData));
+  data->cb = cb;
+  data->cls = cls;
+  data->peer = peer;
+  op = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Operation));
+  op->operation_id = controller->operation_counter++;
+  op->type = OP_PEER_CREATE;
+  op->data = data;
   config = GNUNET_CONFIGURATION_serialize (cfg, &c_size);
   xc_size = GNUNET_TESTBED_compress_config_ (config, c_size, &xconfig);
   GNUNET_free (config);
@@ -100,12 +114,15 @@ GNUNET_TESTBED_peer_create_with_id_ (uint32_t unique_id,
   memmove (&msg[1], msg, xc_size); /* Move the compressed config */
   msg->header.size = htons (msize);
   msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_CREATEPEER);
+  msg->operation_id = GNUNET_htonll (op->operation_id);
   msg->host_id = htonl (GNUNET_TESTBED_host_get_id_ (peer->host));
   msg->peer_id = htonl (peer->unique_id);
   msg->config_size = htonl (c_size);
+  GNUNET_CONTAINER_DLL_insert_tail (peer->controller->op_head,
+                                    peer->controller->op_tail, op);
   GNUNET_TESTBED_queue_message_ (controller,
                                 (struct GNUNET_MessageHeader *) msg);
-  return peer;
+  return op;
 }
 
 
@@ -133,19 +150,24 @@ GNUNET_TESTBED_peer_create_with_id_ (uint32_t unique_id,
  * @param controller controller process to use
  * @param host host to run the peer on
  * @param cfg configuration to use for the peer
- * @return handle to the peer (actual startup will happen asynchronously)
+ * @param cb the callback to call when the peer has been created
+ * @param cls the closure to the above callback
+ * @return the operation handle
  */
-struct GNUNET_TESTBED_Peer *
+struct GNUNET_TESTBED_Operation *
 GNUNET_TESTBED_peer_create (struct GNUNET_TESTBED_Controller *controller,
                            struct GNUNET_TESTBED_Host *host,
-                           const struct GNUNET_CONFIGURATION_Handle *cfg)
+                           const struct GNUNET_CONFIGURATION_Handle *cfg,
+                           GNUNET_TESTBED_PeerCreateCallback cb,
+                           void *cls)
 {
   static uint32_t id_gen;
 
   return GNUNET_TESTBED_peer_create_with_id_ (++id_gen,
                                              controller,
                                              host,
-                                             cfg);
+                                             cfg,
+                                             cb, cls);
 }
 
 
index ee5ec3bd98585b3d0f6b4cffd90138c906d11f67..83d2d890f6c1dc3fd22e3686b022b4bb19595878 100644 (file)
@@ -78,6 +78,29 @@ struct GNUNET_TESTBED_Peer
 };
 
 
+/**
+ * Data for the OperationType OP_PEER_CREATE
+ */
+struct PeerCreateData
+{
+  /**
+   * THe call back to call when we receive peer create success message
+   */
+  GNUNET_TESTBED_PeerCreateCallback cb;
+  
+  /**
+   * The closure for the above callback
+   */
+  void *cls;
+
+  /**
+   * The peer structure to return when we get success message
+   */
+  struct GNUNET_TESTBED_Peer *peer;
+
+};
+
+
 /**
  * Data for the OperationType OP_PEER_DESTROY;
  */
@@ -119,13 +142,17 @@ struct PeerDestroyData
  * @param controller controller process to use
  * @param host host to run the peer on
  * @param cfg configuration to use for the peer
- * @return handle to the peer (actual startup will happen asynchronously)
+ * @param cb the callback to call when the peer has been created
+ * @param cls the closure to the above callback
+ * @return the operation handle
  */
-struct GNUNET_TESTBED_Peer *
+struct GNUNET_TESTBED_Operation *
 GNUNET_TESTBED_peer_create_with_id_ (uint32_t unique_id,
-                                    struct GNUNET_TESTBED_Controller *controller,                                   
+                                    struct GNUNET_TESTBED_Controller *controller,
                                     struct GNUNET_TESTBED_Host *host,
-                                    const struct GNUNET_CONFIGURATION_Handle *cfg);
+                                    const struct GNUNET_CONFIGURATION_Handle *cfg,
+                                    GNUNET_TESTBED_PeerCreateCallback cb,
+                                    void *cls);