summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2018-01-21 18:46:18 +0100
committerChristian Grothoff <christian@grothoff.org>2018-01-21 18:49:47 +0100
commitd09beecc8f5f111538208b7b8da100e0a7015cda (patch)
tree7eff30b0adf7149b7c55feecdc4963e80a319814
parent41cb8b4c513d8c5628f744b48bf4467b6cc66c81 (diff)
downloadexchange-d09beecc8f5f111538208b7b8da100e0a7015cda.tar.gz
exchange-d09beecc8f5f111538208b7b8da100e0a7015cda.tar.bz2
exchange-d09beecc8f5f111538208b7b8da100e0a7015cda.zip
integrate sigpipe with ain loop
-rw-r--r--src/exchange-lib/Makefile.am1
-rw-r--r--src/exchange-lib/test_exchange_api_new.c33
-rw-r--r--src/exchange-lib/testing_api_loop.c108
-rw-r--r--src/exchange-lib/testing_api_trait_process.c6
-rw-r--r--src/include/taler_testing_lib.h32
5 files changed, 139 insertions, 41 deletions
diff --git a/src/exchange-lib/Makefile.am b/src/exchange-lib/Makefile.am
index 6cf70052b..c8fc4471b 100644
--- a/src/exchange-lib/Makefile.am
+++ b/src/exchange-lib/Makefile.am
@@ -48,6 +48,7 @@ libtalertesting_la_SOURCES = \
testing_api_trait_coin_priv.c \
testing_api_trait_denom_pub.c \
testing_api_trait_denom_sig.c \
+ testing_api_trait_process.c \
testing_api_trait_reserve_priv.c
libtalertesting_la_LIBADD = \
diff --git a/src/exchange-lib/test_exchange_api_new.c b/src/exchange-lib/test_exchange_api_new.c
index 573e900f5..4cf842341 100644
--- a/src/exchange-lib/test_exchange_api_new.c
+++ b/src/exchange-lib/test_exchange_api_new.c
@@ -51,12 +51,6 @@
*/
// static struct TALER_EXCHANGE_Handle *exchange;
-
-/**
- * Pipe used to communicate child death via signal.
- */
-static struct GNUNET_DISK_PipeHandle *sigpipe;
-
/**
* Handle to the exchange process.
*/
@@ -115,24 +109,6 @@ run (void *cls,
}
-/**
- * Signal handler called for SIGCHLD. Triggers the
- * respective handler by writing to the trigger pipe.
- */
-static void
-sighandler_child_death ()
-{
- 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 */
-}
-
-
/**
* Remove files from previous runs
@@ -311,17 +287,8 @@ main (int argc,
}
while (0 != system ("wget -q -t 1 -T 1 http://127.0.0.1:8081/keys -o /dev/null -O /dev/null"));
fprintf (stderr, "\n");
- sigpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO,
- GNUNET_NO, GNUNET_NO);
- GNUNET_assert (NULL != sigpipe);
- shc_chld = GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD,
- &sighandler_child_death);
result = TALER_TESTING_setup (&run, NULL);
-
- GNUNET_SIGNAL_handler_uninstall (shc_chld);
- shc_chld = NULL;
- GNUNET_DISK_pipe_close (sigpipe);
GNUNET_break (0 ==
GNUNET_OS_process_kill (exchanged,
SIGTERM));
diff --git a/src/exchange-lib/testing_api_loop.c b/src/exchange-lib/testing_api_loop.c
index d1e153af6..22d786703 100644
--- a/src/exchange-lib/testing_api_loop.c
+++ b/src/exchange-lib/testing_api_loop.c
@@ -45,6 +45,12 @@ struct TALER_TESTING_Interpreter
struct GNUNET_SCHEDULER_Task *task;
/**
+ * ID of task called whenever we get a SIGCHILD.
+ * Used for #TALER_TESTING_wait_for_sigchld().
+ */
+ struct GNUNET_SCHEDULER_Task *child_death_task;
+
+ /**
* Main execution context for the main loop.
*/
struct GNUNET_CURL_Context *ctx;
@@ -70,15 +76,18 @@ struct TALER_TESTING_Interpreter
*/
int result;
- /**
- * Pipe used to communicate child death via signal.
- */
- struct GNUNET_DISK_PipeHandle *sigpipe;
-
};
/**
+ * Pipe used to communicate child death via signal.
+ * Must be global, as used in signal handler!
+ */
+static struct GNUNET_DISK_PipeHandle *sigpipe;
+
+
+
+/**
* Lookup command by label.
*
* @param is interpreter state to search
@@ -263,6 +272,67 @@ do_timeout (void *cls)
}
+/**
+ * Task triggered whenever we receive a SIGCHLD (child
+ * process died).
+ *
+ * @param cls closure
+ */
+static void
+maint_child_death (void *cls)
+{
+ struct TALER_TESTING_Interpreter *is = cls;
+ struct TALER_TESTING_Command *cmd = &is->commands[is->ip];
+ const struct GNUNET_DISK_FileHandle *pr;
+ struct GNUNET_OS_Process **processp;
+ char c[16];
+
+ is->child_death_task = NULL;
+ pr = GNUNET_DISK_pipe_handle (sigpipe,
+ GNUNET_DISK_PIPE_END_READ);
+ GNUNET_break (0 <
+ GNUNET_DISK_file_read (pr,
+ &c,
+ sizeof (c)));
+ if (GNUNET_OK !=
+ TALER_TESTING_get_trait_process (cmd,
+ NULL,
+ &processp))
+ {
+ GNUNET_break (0);
+ TALER_TESTING_interpreter_fail (is);
+ return;
+ }
+ GNUNET_OS_process_wait (*processp);
+ GNUNET_OS_process_destroy (*processp);
+ *processp = NULL;
+ TALER_TESTING_interpreter_next (is);
+}
+
+
+/**
+ * Wait until we receive SIGCHLD signal.
+ * Then obtain the process trait of the current
+ * command, wait on the the zombie and continue
+ * with the next command.
+ */
+void
+TALER_TESTING_wait_for_sigchld (struct TALER_TESTING_Interpreter *is)
+{
+ const struct GNUNET_DISK_FileHandle *pr;
+
+ GNUNET_assert (NULL == is->child_death_task);
+ pr = GNUNET_DISK_pipe_handle (sigpipe,
+ GNUNET_DISK_PIPE_END_READ);
+ is->child_death_task
+ = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
+ pr,
+ &maint_child_death,
+ is);
+
+}
+
+
void
TALER_TESTING_run (struct TALER_TESTING_Interpreter *is,
struct TALER_TESTING_Command *commands)
@@ -298,6 +368,25 @@ struct MainContext
};
+/**
+ * Signal handler called for SIGCHLD. Triggers the
+ * respective handler by writing to the trigger pipe.
+ */
+static void
+sighandler_child_death ()
+{
+ 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 void
main_wrapper (void *cls)
{
@@ -326,12 +415,21 @@ TALER_TESTING_setup (TALER_TESTING_Main main_cb,
.main_cb_cls = main_cb_cls,
.is = &is
};
+ struct GNUNET_SIGNAL_Context *shc_chld;
memset (&is,
0,
sizeof (is));
+ sigpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO,
+ GNUNET_NO, GNUNET_NO);
+ GNUNET_assert (NULL != sigpipe);
+ shc_chld = GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD,
+ &sighandler_child_death);
GNUNET_SCHEDULER_run (&main_wrapper,
&main_ctx);
+ GNUNET_SIGNAL_handler_uninstall (shc_chld);
+ GNUNET_DISK_pipe_close (sigpipe);
+ sigpipe = NULL;
return is.result;
}
diff --git a/src/exchange-lib/testing_api_trait_process.c b/src/exchange-lib/testing_api_trait_process.c
index 2e2e0e137..877eca973 100644
--- a/src/exchange-lib/testing_api_trait_process.c
+++ b/src/exchange-lib/testing_api_trait_process.c
@@ -44,8 +44,8 @@ TALER_TESTING_get_trait_process (const struct TALER_TESTING_Command *cmd,
struct GNUNET_OS_Process ***processp)
{
return cmd->traits (cmd->cls,
- (void **) coin_priv,
- TALER_TESTING_TRAIT_COIN_PRIVATE_KEY,
+ (void **) processp,
+ TALER_TESTING_TRAIT_PROCESS,
selector);
}
@@ -57,7 +57,7 @@ TALER_TESTING_make_trait_process (const char *selector,
struct TALER_TESTING_Trait ret = {
.selector = selector,
.trait_name = TALER_TESTING_TRAIT_PROCESS,
- .ptr = (const void *) process
+ .ptr = (const void *) processp
};
return ret;
diff --git a/src/include/taler_testing_lib.h b/src/include/taler_testing_lib.h
index 949297713..8e1191685 100644
--- a/src/include/taler_testing_lib.h
+++ b/src/include/taler_testing_lib.h
@@ -162,6 +162,16 @@ struct TALER_TESTING_Command
TALER_TESTING_cmd_end (void);
+/**
+ * Wait until we receive SIGCHLD signal.
+ * Then obtain the process trait of the current
+ * command, wait on the the zombie and continue
+ * with the next command.
+ */
+void
+TALER_TESTING_wait_for_sigchld (struct TALER_TESTING_Interpreter *is);
+
+
void
TALER_TESTING_run (struct TALER_TESTING_Interpreter *is,
struct TALER_TESTING_Command *commands);
@@ -272,6 +282,28 @@ TALER_TESTING_get_trait_reserve_priv (const struct TALER_TESTING_Command *cmd,
struct TALER_ReservePrivateKeyP **reserve_priv);
+
+/**
+ * Obtain location where a command stores a pointer to a process
+ *
+ * @param cmd command to extract trait from
+ * @param selector which process to pick if @a cmd has multiple on offer
+ * @param coin_priv[out] set to address of the pointer to the process
+ * @return #GNUNET_OK on success
+ */
+int
+TALER_TESTING_get_trait_process (const struct TALER_TESTING_Command *cmd,
+ const char *selector,
+ struct GNUNET_OS_Process ***processp);
+
+
+
+
+struct TALER_TESTING_Trait
+TALER_TESTING_make_trait_process (const char *selector,
+ struct GNUNET_OS_Process **processp);
+
+
/**
* @param selector
*/