gnunet-svn
[Top][All Lists]
Advanced

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

[gnunet] branch master updated: - added testing cmd child management


From: gnunet
Subject: [gnunet] branch master updated: - added testing cmd child management
Date: Sun, 25 Apr 2021 16:05:06 +0200

This is an automated email from the git hooks/post-receive script.

t3sserakt pushed a commit to branch master
in repository gnunet.

The following commit(s) were added to refs/heads/master by this push:
     new 9ffa19269 - added testing cmd child management
     new cef6317f1 Merge branch 'master' of ssh://gnunet.org/gnunet
9ffa19269 is described below

commit 9ffa19269054bf1e569fe584c0c51a00205a735d
Author: t3sserakt <t3ss@posteo.de>
AuthorDate: Sun Apr 25 16:01:49 2021 +0200

    - added testing cmd child management
---
 src/include/gnunet_child_management_lib.h |  72 ++++++++++
 src/util/child_management.c               | 219 ++++++++++++++++++++++++++++++
 2 files changed, 291 insertions(+)

diff --git a/src/include/gnunet_child_management_lib.h 
b/src/include/gnunet_child_management_lib.h
new file mode 100644
index 000000000..465f71f0e
--- /dev/null
+++ b/src/include/gnunet_child_management_lib.h
@@ -0,0 +1,72 @@
+/*
+      This file is part of GNUnet
+      Copyright (C) 2021 GNUnet e.V.
+
+      GNUnet is free software: you can redistribute it and/or modify it
+      under the terms of the GNU Affero General Public License as published
+      by the Free Software Foundation, either version 3 of the License,
+      or (at your option) any later version.
+
+      GNUnet is distributed in the hope that it will be useful, but
+      WITHOUT ANY WARRANTY; without even the implied warranty of
+      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+      Affero General Public License for more details.
+
+      You should have received a copy of the GNU Affero General Public License
+      along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+     SPDX-License-Identifier: AGPL3.0-or-later
+ */
+
+/**
+ * @file include/anastasis_util_lib.h
+ * @brief GNUnet child management api
+ * @author Christian Grothoff
+ * @author Dominik Meister
+ * @author Dennis Neufeld
+ * @author t3sserakt
+ */
+#ifndef GNUNET_CHILD_MANAGEMENT_LIB_H
+#define GNUNET_CHILD_MANAGEMENT_LIB_H
+
+/**
+ * Handle for the child management
+ */
+struct GNUNET_ChildWaitHandle;
+
+/**
+ * Defines a GNUNET_ChildCompletedCallback which is sent back
+ * upon death or completion of a child process.
+ *
+ * @param cls handle for the callback
+ * @param type type of the process
+ * @param exit_code status code of the process
+ *
+*/
+typedef void
+(*GNUNET_ChildCompletedCallback)(void *cls,
+                                 enum GNUNET_OS_ProcessStatusType type,
+                                 long unsigned int exit_code);
+
+/**
+ * Starts the handling of the child processes.
+ * Function checks the status of the child process and sends back a
+ * GNUNET_ChildCompletedCallback upon completion/death of the child.
+ *
+ * @param proc child process which is monitored
+ * @param cb reference to the callback which is called after completion
+ * @param cb_cls closure for the callback
+ * @return GNUNET_ChildWaitHandle is returned
+ */
+struct GNUNET_ChildWaitHandle *
+GNUNET_wait_child (struct GNUNET_OS_Process *proc,
+                   GNUNET_ChildCompletedCallback cb,
+                   void *cb_cls);
+
+/**
+ * Stop waiting on this child.
+ */
+void
+GNUNET_wait_child_cancel (struct GNUNET_ChildWaitHandle *cwh);
+
+#endif
diff --git a/src/util/child_management.c b/src/util/child_management.c
new file mode 100644
index 000000000..7edc33dc1
--- /dev/null
+++ b/src/util/child_management.c
@@ -0,0 +1,219 @@
+/*
+      This file is part of GNUnet
+      Copyright (C) 2021 GNUnet e.V.
+
+      GNUnet is free software: you can redistribute it and/or modify it
+      under the terms of the GNU Affero General Public License as published
+      by the Free Software Foundation, either version 3 of the License,
+      or (at your option) any later version.
+
+      GNUnet is distributed in the hope that it will be useful, but
+      WITHOUT ANY WARRANTY; without even the implied warranty of
+      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+      Affero General Public License for more details.
+
+      You should have received a copy of the GNU Affero General Public License
+      along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+     SPDX-License-Identifier: AGPL3.0-or-later
+ */
+
+/**
+ * @file testing/child_management.c
+ * @brief Handling of child processes in GNUnet.
+ * @author Christian Grothoff (ANASTASIS)
+ * @author Dominik Meister (ANASTASIS)
+ * @author t3sserakt
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_child_management_lib.h"
+
+
+/**
+ * Struct which defines a Child Wait handle
+ */
+struct GNUNET_ChildWaitHandle
+{
+  /**
+   * Linked list to the next child
+   */
+  struct GNUNET_ChildWaitHandle *next;
+  /**
+   * Linked list to the previous child
+   */
+  struct GNUNET_ChildWaitHandle *prev;
+  /**
+   * Child process which is managed
+   */
+  struct GNUNET_OS_Process *proc;
+  /**
+   * Callback which is called upon completion/death of the child task
+   */
+  GNUNET_ChildCompletedCallback cb;
+  /**
+   * Closure for the handle
+   */
+  void *cb_cls;
+};
+
+
+/**
+ * Pipe used to communicate shutdown via signal.
+ */
+static struct GNUNET_DISK_PipeHandle *sigpipe;
+
+static struct GNUNET_SIGNAL_Context *shc_chld;
+
+static struct GNUNET_SCHEDULER_Task *sig_task;
+
+static struct GNUNET_ChildWaitHandle *cwh_head;
+
+static struct GNUNET_ChildWaitHandle *cwh_tail;
+
+/**
+ * Task triggered whenever we receive a SIGCHLD (child
+ * process died) or when user presses CTRL-C.
+ *
+ * @param cls closure, NULL
+ */
+static void
+maint_child_death (void *cls)
+{
+  char buf[16];
+  const struct GNUNET_DISK_FileHandle *pr;
+  struct GNUNET_ChildWaitHandle *nxt;
+
+  (void) cls;
+  sig_task = NULL;
+  /* drain pipe */
+  pr = GNUNET_DISK_pipe_handle (sigpipe,
+                                GNUNET_DISK_PIPE_END_READ);
+  GNUNET_assert (! GNUNET_DISK_handle_invalid (pr));
+
+  (void) GNUNET_DISK_file_read (pr,
+                                buf,
+                                sizeof(buf));
+
+  /* find applicable processes that exited */
+  for (struct GNUNET_ChildWaitHandle *cwh = cwh_head;
+       NULL != cwh;
+       cwh = nxt)
+  {
+    enum GNUNET_OS_ProcessStatusType type;
+    long unsigned int exit_code = 0;
+
+    nxt = cwh->next;
+    if (GNUNET_OK ==
+        GNUNET_OS_process_status (cwh->proc,
+                                  &type,
+                                  &exit_code))
+    {
+      GNUNET_CONTAINER_DLL_remove (cwh_head,
+                                   cwh_tail,
+                                   cwh);
+      cwh->cb (cwh->cb_cls,
+               type,
+               exit_code);
+      GNUNET_free (cwh);
+    }
+  }
+  if (NULL == cwh_head)
+    return;
+  /* wait for more */
+  sig_task = GNUNET_SCHEDULER_add_read_file (
+    GNUNET_TIME_UNIT_FOREVER_REL,
+    GNUNET_DISK_pipe_handle (sigpipe,
+                             GNUNET_DISK_PIPE_END_READ),
+    &maint_child_death,
+    NULL);
+}
+
+
+/**
+ * Signal handler called for SIGCHLD.  Triggers the
+ * respective handler by writing to the trigger pipe.
+ */
+static void
+sighandler_child_death (void)
+{
+  static char c;
+  int old_errno = errno; /* back-up errno */
+
+  GNUNET_break (
+    1 ==
+    GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle (sigpipe,
+                                                     
GNUNET_DISK_PIPE_END_WRITE),
+                            &c,
+                            sizeof(c)));
+  errno = old_errno; /* restore errno */
+}
+
+
+void __attribute__ ((constructor))
+child_management_start ()
+{
+  if (NULL != sigpipe)
+    return; /* already initialized */
+  sigpipe = GNUNET_DISK_pipe (GNUNET_DISK_PF_NONE);
+  GNUNET_assert (sigpipe != NULL);
+  shc_chld =
+    GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, &sighandler_child_death);
+}
+
+
+struct GNUNET_ChildWaitHandle *
+GNUNET_wait_child (struct GNUNET_OS_Process *proc,
+                   GNUNET_ChildCompletedCallback cb,
+                   void *cb_cls)
+{
+  struct GNUNET_ChildWaitHandle *cwh;
+
+  child_management_start ();
+  cwh = GNUNET_new (struct GNUNET_ChildWaitHandle);
+  cwh->proc = proc;
+  cwh->cb = cb;
+  cwh->cb_cls = cb_cls;
+  GNUNET_CONTAINER_DLL_insert (cwh_head,
+                               cwh_tail,
+                               cwh);
+  if (NULL == sig_task)
+  {
+    sig_task = GNUNET_SCHEDULER_add_read_file (
+      GNUNET_TIME_UNIT_FOREVER_REL,
+      GNUNET_DISK_pipe_handle (sigpipe,
+                               GNUNET_DISK_PIPE_END_READ),
+      &maint_child_death,
+      NULL);
+  }
+  return cwh;
+}
+
+
+void
+GNUNET_wait_child_cancel (struct GNUNET_ChildWaitHandle *cwh)
+{
+  GNUNET_CONTAINER_DLL_remove (cwh_head,
+                               cwh_tail,
+                               cwh);
+  if (NULL == cwh_head)
+  {
+    GNUNET_SCHEDULER_cancel (sig_task);
+    sig_task = NULL;
+  }
+  GNUNET_free (cwh);
+}
+
+
+/**
+ * Clean up.
+ */
+void __attribute__ ((destructor))
+GNUNET_CM_done ()
+{
+  GNUNET_assert (NULL == sig_task);
+  GNUNET_SIGNAL_handler_uninstall (shc_chld);
+  shc_chld = NULL;
+  GNUNET_DISK_pipe_close (sigpipe);
+  sigpipe = NULL;
+}

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

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