stop peers before destroying them
authorSree Harsha Totakura <totakura@in.tum.de>
Fri, 31 Aug 2012 10:05:09 +0000 (10:05 +0000)
committerSree Harsha Totakura <totakura@in.tum.de>
Fri, 31 Aug 2012 10:05:09 +0000 (10:05 +0000)
src/testbed/test_testbed_api_testbed_run.c
src/testbed/testbed_api_testbed.c

index b9fd60d35cfb130881d0f52399b8758d87aef96d..31b6330325525363f0bd17f605d1990a4bbf8494 100644 (file)
@@ -31,7 +31,7 @@
 /**
  * Number of peers we want to start
  */
-#define NUM_PEERS 2
+#define NUM_PEERS 50
 
 /**
  * The array of peers; we fill this as the peers are given to us by the testbed
@@ -119,7 +119,7 @@ controller_event_cb (void *cls,
     peers[peer_id++] = event->details.peer_start.peer;
     break;
   default:
-    GNUNET_break (0);
+    GNUNET_assert (0);
   }
 }
 
@@ -144,8 +144,8 @@ run (void *cls, char *const *args, const char *cfgfile,
   event_mask |= (1LL << GNUNET_TESTBED_ET_CONNECT);
   event_mask |= (1LL << GNUNET_TESTBED_ET_DISCONNECT);
   event_mask |= (1LL << GNUNET_TESTBED_ET_OPERATION_FINISHED);
-  GNUNET_TESTBED_run (NULL, config, 2, event_mask, &controller_event_cb,
-                           NULL, &master_task, NULL);
+  GNUNET_TESTBED_run (NULL, config, NUM_PEERS, event_mask, &controller_event_cb,
+                      NULL, &master_task, NULL);
   abort_task = GNUNET_SCHEDULER_add_delayed 
     (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5), &do_abort, NULL);
 }
index e20b3a10a97244ad2a897267489eddc7f2e19ff3..914523780e3c7af8f8e76fc3ef463f61fa4a9d65 100644 (file)
@@ -75,6 +75,34 @@ struct DLLOperation
 };
 
 
+/**
+ * States of RunContext
+ */
+enum State 
+{
+  /**
+   * Initial state
+   */
+  RC_INIT = 0,
+  
+  /**
+   * Peers have been started
+   */
+  RC_PEERS_STARTED,
+
+  /**
+   * Peers are stopped
+   */
+  RC_PEERS_STOPPED,
+  
+  /**
+   * Peers are destroyed
+   */
+  RC_PEERS_DESTROYED
+
+};
+
+
 /**
  * Testbed Run Handle
  */
@@ -135,6 +163,11 @@ struct RunContext
    */
   uint64_t event_mask;
 
+  /**
+   * State of this context
+   */
+  enum State state;
+
   /**
    * Current peer count for an operation; Set this to 0 and increment for each
    * successful operation on a peer
@@ -146,11 +179,6 @@ struct RunContext
    */
   unsigned int num_peers;
 
-  /**
-   * Are we cleaning up?
-   */
-  int in_shutdown;  
-
 };
 
 
@@ -306,6 +334,7 @@ cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
   struct DLLOperation *dll_op;  
   
   GNUNET_assert (NULL == rc->peers);
+  GNUNET_assert (RC_PEERS_DESTROYED == rc->state);
   if (NULL != rc->c)
     GNUNET_TESTBED_controller_disconnect (rc->c);
   if (NULL != rc->cproc)
@@ -339,13 +368,20 @@ event_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event)
 {
   struct RunContext *rc = cls;
   struct DLLOperation *dll_op;
+  unsigned int peer_id;
   
-  if ((GNUNET_YES == rc->in_shutdown) && 
-      (GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type))
+
+  if ((RC_INIT != rc->state) && 
+      ((GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type)||
+       (GNUNET_TESTBED_ET_PEER_STOP == event->type)))
   {
     for (dll_op = rc->dll_op_head; NULL != dll_op; dll_op = dll_op->next)
     {
-      if (event->details.operation_finished.operation == dll_op->op)
+      if ((GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type) && 
+          (event->details.operation_finished.operation == dll_op->op))
+        break;
+      if ((GNUNET_TESTBED_ET_PEER_STOP == event->type) &&
+          (event->details.peer_stop.peer == dll_op->cls))
         break;
     }
     if (NULL == dll_op)
@@ -356,11 +392,30 @@ event_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event)
     rc->peer_count++;
     if (rc->peer_count < rc->num_peers)
       return;
-    GNUNET_free (rc->peers);
-    rc->peers = NULL;    
-    LOG (GNUNET_ERROR_TYPE_DEBUG, "All peers successfully destroyed\n");
-    GNUNET_SCHEDULER_add_now (&cleanup_task, rc);
-    return;    
+    switch (rc->state)
+    {
+    case RC_PEERS_STARTED:
+      rc->state = RC_PEERS_STOPPED;
+      rc->peer_count = 0;
+      for (peer_id = 0; peer_id < rc->num_peers; peer_id++)
+      {
+        dll_op = GNUNET_malloc (sizeof (struct DLLOperation));
+        dll_op->op = GNUNET_TESTBED_peer_destroy (rc->peers[peer_id]);
+        GNUNET_CONTAINER_DLL_insert_tail (rc->dll_op_head, rc->dll_op_tail,
+                                          dll_op);
+      }
+      break;
+    case RC_PEERS_STOPPED:
+      rc->state = RC_PEERS_DESTROYED;
+      GNUNET_free (rc->peers);
+      rc->peers = NULL;
+      LOG (GNUNET_ERROR_TYPE_DEBUG, "All peers successfully destroyed\n");
+      GNUNET_SCHEDULER_add_now (&cleanup_task, rc);
+      break;
+    default:
+      GNUNET_assert (0);
+    }
+    return;
   }
 
  call_cc:
@@ -378,7 +433,8 @@ event_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event)
   rc->peer_count++;
   if (rc->peer_count < rc->num_peers)
     return;
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "Peers started successfully\n");  
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "Peers started successfully\n");
+  rc->state = RC_PEERS_STARTED;
   GNUNET_SCHEDULER_add_continuation (rc->master, rc->master_cls,
                                      GNUNET_SCHEDULER_REASON_PREREQ_DONE);  
 }
@@ -434,10 +490,9 @@ void
 shutdown_run_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {  
   struct RunContext *rc = cls;
-  struct DLLOperation *dll_op;  
+  struct DLLOperation *dll_op;
   unsigned int peer;
   
-  rc->in_shutdown = GNUNET_YES;
   if (NULL != rc->c)
   {
     if (NULL != rc->peers)
@@ -446,13 +501,16 @@ shutdown_run_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
       for (peer = 0; peer < rc->num_peers; peer++)
       {
         dll_op = GNUNET_malloc (sizeof (struct DLLOperation));
-        dll_op->op = GNUNET_TESTBED_peer_destroy (rc->peers[peer]);
+        dll_op->op = GNUNET_TESTBED_peer_stop (rc->peers[peer]);
+        dll_op->cls = rc->peers[peer];
         GNUNET_CONTAINER_DLL_insert_tail (rc->dll_op_head, rc->dll_op_tail,
-                                          dll_op);        
-      }      
+                                          dll_op);
+      }
       return;
     }
   }
+  rc->state = RC_PEERS_DESTROYED; /* No peers are present so we consider the
+                                     state where all peers are destroyed  */
   GNUNET_SCHEDULER_add_now (&cleanup_task, rc);
 }
 
@@ -508,7 +566,7 @@ GNUNET_TESTBED_run (const char *host_filename,
   rc->cc_cls = cc_cls;
   rc->master = master;
   rc->master_cls = master_cls;
-  rc->in_shutdown = GNUNET_NO;
+  rc->state = RC_INIT;
   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
                                 &shutdown_run_task, rc);
 }