gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r30838 - msh/src


From: gnunet
Subject: [GNUnet-SVN] r30838 - msh/src
Date: Thu, 21 Nov 2013 10:57:56 +0100

Author: harsha
Date: 2013-11-21 10:57:55 +0100 (Thu, 21 Nov 2013)
New Revision: 30838

Modified:
   msh/src/mshd.c
Log:
- fork address lookup server


Modified: msh/src/mshd.c
===================================================================
--- msh/src/mshd.c      2013-11-21 09:31:40 UTC (rev 30837)
+++ msh/src/mshd.c      2013-11-21 09:57:55 UTC (rev 30838)
@@ -134,6 +134,11 @@
   MODE_SERV,
 
   /**
+   * In this mode we only server address lookups via UNIX domain sockets
+   */
+  MODE_LOCAL_SERV,
+
+  /**
    * Worker mode
    */
   MODE_WORKER
@@ -142,6 +147,28 @@
 
 
 /**
+ * Context information for the child processes we start
+ */
+struct ChildProc
+{
+  /**
+   * DLL next
+   */
+  struct ChildProc *next;
+
+  /**
+   * DLL prev
+   */
+  struct ChildProc *prev;
+
+  /**
+   * The process id of the child process
+   */
+  pid_t pid;
+};
+
+
+/**
  * Mapping for instance addresses
  */
 AddressMap *addrmap;
@@ -173,6 +200,16 @@
 /****************************/
 
 /**
+ * DLL head for the child process contexts
+ */
+static struct ChildProc *chld_head;
+
+/**
+ * DLL tail for the child process contexts
+ */
+static struct ChildProc *chld_tail;
+
+/**
  * DLL head for address verification contexts
  */
 static struct VerifyAddressesCtx *vactx_head;
@@ -325,12 +362,28 @@
 static void
 do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
+  struct ChildProc *chld;
   shutdown_task = GNUNET_SCHEDULER_NO_TASK;
   switch (mode)
   {
   case MODE_PROBE:
     break;
   case MODE_SERV:
+    if (NULL != (chld = chld_head))
+    {
+      LOG_DEBUG ("Delaying shutdown\n");
+      shutdown_task = GNUNET_SCHEDULER_add_delayed
+           (GNUNET_TIME_UNIT_FOREVER_REL, &do_shutdown, NULL);
+      while (NULL != chld)
+      {
+        GNUNET_break (0 == kill (chld->pid, SIGTERM));
+        chld = chld->next;
+      }
+      return;
+    }
+    MSH_pmonitor_shutdown ();
+    break;
+  case MODE_LOCAL_SERV:
     shutdown_local_server ();
     MSH_pmonitor_shutdown ();
     break;
@@ -462,7 +515,6 @@
 spawn_worker (struct GNUNET_CONNECTION_Handle *conn)
 {
   pid_t ret;
-  int listen_fd;
 
   ret = fork ();
   if (0 != ret)
@@ -531,6 +583,8 @@
     if (0 == pid)               /* state is cleared and hence we return */
       return;
     break;
+  case MODE_LOCAL_SERV:
+    GNUNET_assert (0);
   case MODE_WORKER:
     GNUNET_assert (0);
   }
@@ -602,8 +656,8 @@
 
 
 /**
- * Callbacks of this type can be supplied to MSH_monitor_process() to be
- * notified when the corresponding processes exits.
+ * This callback is called when the process that we start from the forked local
+ * server exits.  The local server is forked from MPI instances 0.
  *
  * @param cls the closure passed to MSH_monitor_process()
  * @param type the process status type
@@ -616,11 +670,31 @@
   proc = NULL;
   LOG (GNUNET_ERROR_TYPE_INFO, "Main process died.  Exiting.\n"); 
   GNUNET_SCHEDULER_shutdown ();
-  send_term_signal ();
 }
 
 
 /**
+ * This callback is called when the local server that we forked is exited.
+ * Shutdown our instance then.
+ *
+ * @param cls the closure passed to MSH_monitor_process()
+ * @param type the process status type
+ * @param long the return/exit code of the process
+ */
+static void
+local_serv_exit_cb (void *cls, enum GNUNET_OS_ProcessStatusType type, int code)
+{
+  struct ChildProc *chld = cls;
+
+  GNUNET_CONTAINER_DLL_remove (chld_head, chld_tail, chld);
+  LOG (GNUNET_ERROR_TYPE_INFO, "Local server died.  Exiting. \n");
+  GNUNET_SCHEDULER_shutdown ();
+  if (0 == rank)
+    send_term_signal ();
+}
+
+
+/**
  * Task for running a round
  *
  * @param cls NULL
@@ -636,6 +710,7 @@
 static void
 schedule_next_round ()
 {
+  struct ChildProc *chld;
   intmax_t pid;
   int total_rounds;
 
@@ -656,7 +731,6 @@
   LOG_DEBUG ("Verification phase complete; commencing reduction phase\n");
   GNUNET_break (GNUNET_OK == reduce_ntree ());
   addressmap_print (addrmap);
-  rmap = addressmap_create_reverse_mapping (addrmap);
   pid = (intmax_t) getpid ();
   GNUNET_assert (0 < asprintf (&unixpath, "%ju.sock", pid));
   hostsfile = GNUNET_DISK_mktemp ("MSHD_HOSTS");
@@ -665,32 +739,71 @@
     GNUNET_SCHEDULER_shutdown ();
     return;
   }
+  GNUNET_assert (NULL != bitmap);
+  bitmap_destroy (bitmap);
+  bitmap = NULL;
   setenv (MSHD_HOSTSFILE, hostsfile, 1);
   setenv (MSHD_SOCK_NAME, unixpath, 1);
-  init_local_server (unixpath);
+  pid = fork ();
+  if (-1 == pid)
+  {
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  if (0 == pid)
+  {
+    GNUNET_log_setup ("mshd-local-serv", NULL, NULL);
+    rmap = addressmap_create_reverse_mapping (addrmap);
+    init_local_server (unixpath);
+    mode = MODE_LOCAL_SERV;
+    GNUNET_NETWORK_socket_close (listen_socket);
+    listen_socket = NULL;
+    if (0 == rank)
+    {
+      MSH_pmonitor_init ();
+      proc = GNUNET_OS_start_process_vap (GNUNET_NO,
+                                          GNUNET_OS_INHERIT_STD_ALL,
+                                          NULL,
+                                          NULL,
+                                          run_args[0],
+                                          run_args);
+      if (NULL == proc)
+      {
+        LOG_ERROR ("Unable to start process `%s'\n", run_args[0]);
+        GNUNET_SCHEDULER_shutdown ();
+        return;
+      }
+      MSH_monitor_process (proc, &proc_exit_cb, NULL);
+    }
+    return;
+  }
+  GNUNET_assert (NULL != addrmap);
+  addressmap_destroy (addrmap);
+  addrmap = NULL;
+  if (NULL != s_addrs)
+  {
+    GNUNET_free (s_addrs);
+    s_addrs = NULL;
+  }
+  if (NULL != run_args)
+  {
+    free_argv (run_args);
+    run_args = NULL;
+  }
+  if (NULL != hostsfile)
+  {
+    GNUNET_free (hostsfile);
+    hostsfile = NULL;
+  }
+  chld = GNUNET_new (struct ChildProc);
+  chld->pid = pid;
+  GNUNET_CONTAINER_DLL_insert (chld_head, chld_tail, chld);
   MSH_pmonitor_init ();
+  MSH_monitor_process_pid (pid, &local_serv_exit_cb, chld);
   mode = MODE_SERV;
   GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == accept_task);
   accept_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
                                            listen_socket, &accept_conn, NULL);
-  if (0 == rank)
-  {
-    proc = GNUNET_OS_start_process_vap (GNUNET_NO,
-                                        GNUNET_OS_INHERIT_STD_ALL,
-                                        NULL,
-                                        NULL,
-                                        run_args[0],
-                                        run_args);    
-    if (NULL == proc)
-    {
-      LOG_ERROR ("Unable to start process `%s'\n", run_args[0]);
-      GNUNET_SCHEDULER_shutdown ();
-      send_term_signal ();
-      return;
-    }
-    MSH_monitor_process (proc, &proc_exit_cb, NULL);
-    return;
-  }
   poll_shutdown_task = GNUNET_SCHEDULER_add_delayed (POLL_SHUTDOWN_INTERVAL,
                                                      &poll_shutdown, NULL);
 }
@@ -1255,7 +1368,7 @@
   ret = 0;
   
  fail:
-  if (MODE_WORKER == mode)
+  if (MODE_LOCAL_SERV <= mode)
     return ret;
   LOG_DEBUG ("Finalizing...\n");
   GNUNET_break (MPI_SUCCESS == MPI_Finalize());




reply via email to

[Prev in Thread] Current Thread [Next in Thread]