implemented controller error callback
authorSree Harsha Totakura <totakura@in.tum.de>
Thu, 12 Jul 2012 11:50:12 +0000 (11:50 +0000)
committerSree Harsha Totakura <totakura@in.tum.de>
Thu, 12 Jul 2012 11:50:12 +0000 (11:50 +0000)
src/testbed/gnunet-service-testbed.c
src/testbed/testbed_api.c
src/testbed/testbed_api_hosts.c
src/testbed/testbed_api_hosts.h

index 0619a67cb77ccb3ed59a5451f9c8ac155b2098fc..fabfe1691f59fb5bb90f49f667b285a8c914a999 100644 (file)
@@ -1279,7 +1279,6 @@ shutdown_task (void *cls,
   uint32_t id;
 
   shutdown_task_id = GNUNET_SCHEDULER_NO_TASK;
-  GNUNET_SCHEDULER_shutdown ();
   LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down testbed service\n");
   (void) GNUNET_CONTAINER_multihashmap_iterate (ss_map, &ss_map_free_iterator,
                                                 NULL);
index 5070d4f29c19b1667e129c91da56ccc6add9b434..d9aec6197f79d7af375763378d310f5a880987bb 100644 (file)
@@ -430,31 +430,40 @@ struct GNUNET_TESTBED_ControllerProc
    */
   struct GNUNET_TESTBED_HelperHandle *helper;
 
-};
-
-
-/**
- * Context to use while starting a controller
- */
-struct ControllerStartContext
-{
   /**
-   * The error callback
+   * The controller error callback
    */
   GNUNET_TESTBED_ControllerErrorCallback cec;
 
   /**
-   * Closure for the above callback
+   * The closure for the above callback
    */
   void *cec_cls;
 
   /**
-   * error message if any
+   * The task id of the task that will be called when controller dies
    */
-  char *emsg;
+  GNUNET_SCHEDULER_TaskIdentifier controller_dead_task_id;
 };
 
 
+/**
+ * The task which is run when a controller dies (its stdout is closed)
+ *
+ * @param cls the ControllerProc struct
+ * @param tc the context
+ */
+static void
+controller_dead_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct GNUNET_TESTBED_ControllerProc *cproc = cls;
+
+  cproc->controller_dead_task_id = GNUNET_SCHEDULER_NO_TASK;
+  if (NULL != cproc->cec)
+    cproc->cec (cproc->cec_cls, NULL); /* FIXME: How to get the error message? */
+}
+
+
 /**
  * Starts a controller process at the host
  *
@@ -480,7 +489,7 @@ GNUNET_TESTBED_controller_start (struct GNUNET_TESTING_System *system,
                                 void *cec_cls)
 {
   struct GNUNET_TESTBED_ControllerProc *cproc;
-  //struct ControllerStartContext *csc;
+  const struct GNUNET_DISK_FileHandle *read_fh;
   char *cfg_filename;
 
   if ((NULL == host) || (0 == GNUNET_TESTBED_host_get_id_ (host)))
@@ -512,9 +521,20 @@ GNUNET_TESTBED_controller_start (struct GNUNET_TESTING_System *system,
   }
   else
   {
-    GNUNET_break (0);
+    GNUNET_break (0); /* FIXME: start controller remotely */
     return NULL;
   }
+  read_fh = GNUNET_DISK_pipe_handle (cproc->helper->cpipe_out,
+                                    GNUNET_DISK_PIPE_END_READ);
+  if (NULL == read_fh)
+  {
+    GNUNET_break (0); // we can't catch the process 
+  }
+  cproc->cec = cec;
+  cproc->cec_cls = cec_cls;
+  cproc->controller_dead_task_id =
+    GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, read_fh,
+                                   &controller_dead_task, cproc);
   return cproc;
 }
 
@@ -529,6 +549,11 @@ GNUNET_TESTBED_controller_start (struct GNUNET_TESTING_System *system,
 void
 GNUNET_TESTBED_controller_stop (struct GNUNET_TESTBED_ControllerProc *cproc)
 {
+  if (GNUNET_SCHEDULER_NO_TASK != cproc->controller_dead_task_id)
+  {
+    GNUNET_SCHEDULER_cancel (cproc->controller_dead_task_id);
+    cproc->controller_dead_task_id = GNUNET_SCHEDULER_NO_TASK;
+  }
   GNUNET_TESTBED_host_stop_ (cproc->helper);
   GNUNET_free (cproc);
 }
index 2b86074f75802490c14c2bb69feb89472284e936..56df4dedee61354b8528bf8220d8e27330ae5f37 100644 (file)
@@ -33,6 +33,8 @@
 #include "gnunet_hello_lib.h"
 #include "gnunet_container_lib.h"
 
+#include "testbed_api_hosts.h"
+
 /**
  * Generic logging shorthand
  */
@@ -333,33 +335,6 @@ GNUNET_TESTBED_host_destroy (struct GNUNET_TESTBED_Host *host)
 }
 
 
-/**
- * Wrapper around GNUNET_HELPER_Handle
- */
-struct GNUNET_TESTBED_HelperHandle
-{
-  /**
-   * The process handle
-   */
-  struct GNUNET_OS_Process *process;
-
-  /**
-   * Pipe connecting to stdin of the process.
-   */
-  struct GNUNET_DISK_PipeHandle *cpipe;
-
-  /**
-   * The port number for ssh; used for helpers starting ssh
-   */
-  char *port;
-
-  /**
-   * The ssh destination string; used for helpers starting ssh
-   */
-  char *dst; 
-};
-
-
 /**
  * Run a given helper process at the given host.  Communication
  * with the helper will be via GNUnet messages on stdin/stdout.
@@ -381,8 +356,9 @@ GNUNET_TESTBED_host_run_ (const struct GNUNET_TESTBED_Host *host,
   while (NULL != binary_argv[argc]) 
     argc++;
   h = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_HelperHandle));
-  h->cpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_YES, GNUNET_NO);
-  if (NULL == h->cpipe)
+  h->cpipe_in = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_YES, GNUNET_NO);
+  h->cpipe_out = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO, GNUNET_YES);
+  if ((NULL == h->cpipe_in) || (NULL == h->cpipe_out))
   {
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
                         "pipe");
@@ -393,7 +369,7 @@ GNUNET_TESTBED_host_run_ (const struct GNUNET_TESTBED_Host *host,
   {
     h->process = GNUNET_OS_start_process_vap (GNUNET_YES,
                                               GNUNET_OS_INHERIT_STD_ALL,
-                                             h->cpipe, NULL,
+                                             h->cpipe_in, h->cpipe_out,
                                              "gnunet-service-testbed", 
                                              binary_argv);
   }
@@ -423,19 +399,19 @@ GNUNET_TESTBED_host_run_ (const struct GNUNET_TESTBED_Host *host,
     GNUNET_assert (argp == argc + 6 + 1);
     h->process = GNUNET_OS_start_process_vap (GNUNET_YES,
                                               GNUNET_OS_INHERIT_STD_ALL,
-                                             h->cpipe, NULL,
+                                             h->cpipe_in, NULL,
                                              "ssh", 
                                              remote_args);
   }
   if (NULL == h->process)
   {
-    GNUNET_break (GNUNET_OK == GNUNET_DISK_pipe_close (h->cpipe));
+    GNUNET_break (GNUNET_OK == GNUNET_DISK_pipe_close (h->cpipe_in));
     GNUNET_free_non_null (h->port);
     GNUNET_free_non_null (h->dst);
     GNUNET_free (h);
     return NULL;
   } 
-  GNUNET_break (GNUNET_OK == GNUNET_DISK_pipe_close_end (h->cpipe, GNUNET_DISK_PIPE_END_READ));
+  GNUNET_break (GNUNET_OK == GNUNET_DISK_pipe_close_end (h->cpipe_in, GNUNET_DISK_PIPE_END_READ));
   return h;
 }
 
@@ -448,7 +424,8 @@ GNUNET_TESTBED_host_run_ (const struct GNUNET_TESTBED_Host *host,
 void
 GNUNET_TESTBED_host_stop_ (struct GNUNET_TESTBED_HelperHandle *handle)
 {
-  GNUNET_break (GNUNET_OK == GNUNET_DISK_pipe_close (handle->cpipe));
+  GNUNET_break (GNUNET_OK == GNUNET_DISK_pipe_close (handle->cpipe_in));
+  GNUNET_break (GNUNET_OK == GNUNET_DISK_pipe_close (handle->cpipe_out));
   GNUNET_break (0 == GNUNET_OS_process_kill (handle->process, SIGTERM));
   GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (handle->process));
   GNUNET_OS_process_destroy (handle->process);
index 1eab193635bdd383f2b35176d149073361f41dbb..b9a62698c815d86dfe96ad9e685923b6f427b8fa 100644 (file)
 #include "gnunet_helper_lib.h"
 
 
+/**
+ * Wrapper around
+ */
+struct GNUNET_TESTBED_HelperHandle
+{
+  /**
+   * The process handle
+   */
+  struct GNUNET_OS_Process *process;
+
+  /**
+   * Pipe connecting to stdin of the process.
+   */
+  struct GNUNET_DISK_PipeHandle *cpipe_in;
+
+  /**
+   * Pipe from the stdout of the process.
+   */
+  struct GNUNET_DISK_PipeHandle *cpipe_out;
+
+  /**
+   * The port number for ssh; used for helpers starting ssh
+   */
+  char *port;
+
+  /**
+   * The ssh destination string; used for helpers starting ssh
+   */
+  char *dst; 
+};
+
+
 /**
  * Lookup a host by ID.
  *