diff options
Diffstat (limited to 'src/exchange-lib')
| -rw-r--r-- | src/exchange-lib/Makefile.am | 1 | ||||
| -rw-r--r-- | src/exchange-lib/test_exchange_api_new.c | 33 | ||||
| -rw-r--r-- | src/exchange-lib/testing_api_loop.c | 108 | ||||
| -rw-r--r-- | src/exchange-lib/testing_api_trait_process.c | 6 | 
4 files changed, 107 insertions, 41 deletions
| diff --git a/src/exchange-lib/Makefile.am b/src/exchange-lib/Makefile.am index 6cf70052..c8fc4471 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 573e900f..4cf84234 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 d1e153af..22d78670 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 2e2e0e13..877eca97 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; | 
