gnunet-svn
[Top][All Lists]
Advanced

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

[taler-anastasis] branch master updated: new API


From: gnunet
Subject: [taler-anastasis] branch master updated: new API
Date: Wed, 02 Dec 2020 18:35:38 +0100

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

grothoff pushed a commit to branch master
in repository anastasis.

The following commit(s) were added to refs/heads/master by this push:
     new ea45356  new API
     new d069710  Merge branch 'master' of git+ssh://git.taler.net/anastasis
ea45356 is described below

commit ea4535623e42e49290dd17e9f1c38d6048004103
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Wed Dec 2 18:35:30 2020 +0100

    new API
---
 src/util/Makefile.am        |   1 +
 src/util/child_management.c | 168 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 169 insertions(+)

diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index 101641c..06ce9c4 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -31,6 +31,7 @@ lib_LTLIBRARIES = \
 
 libanastasisutil_la_SOURCES = \
   anastasis_crypto.c \
+  child_management.c \
   os_installation.c
 libanastasisutil_la_LIBADD = \
   -lgnunetutil \
diff --git a/src/util/child_management.c b/src/util/child_management.c
new file mode 100644
index 0000000..e6947a0
--- /dev/null
+++ b/src/util/child_management.c
@@ -0,0 +1,168 @@
+struct ANASTASIS_ChildWaitHandle
+{
+  struct ANASTASIS_ChildWaitHandle *next;
+  struct ANASTASIS_ChildWaitHandle *prev;
+  struct GNUNET_OS_Process *proc;
+  ANASTASIS_ChildCompletedCallback cb;
+  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 ANASTASIS_ChildWaitHandle *cwh_head;
+
+static struct ANASTASIS_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;
+
+  (void) cls;
+  sig_task = NULL;
+  /* drain pipe */
+  pr = GNUNET_DISK_pipe_handle (shutdown_pipe_handle,
+                                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 ANASTASIS_ChildWaitHandle *cwh = cwh_head;
+       NULL != cwh;
+       cwh = next)
+  {
+    enum GNUNET_OS_ProcessStatusType type;
+    long unsigned int exit_code = 0;
+
+    struct ANASTASIS_ChildWaitHandle *next = 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 */
+}
+
+
+static int
+child_management_start (void)
+{
+  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 ANASTASIS_ChildWaitHandle *
+ANASTASIS_wait_child (struct GNUNET_OS_Process *proc,
+                      ANASTASIS_ChildCompletedCallback cb,
+                      void *cb_cls)
+{
+  struct ANASTASIS_ChildWaitHandle *cwh;
+
+  cwh = GNUNET_new (struct ANASTASIS_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
+ANASTASIS_wait_child_cancel (struct ANASTASIS_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))
+ANASTASIS_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]