fix signal initialization race on startup with shutdown

This commit is contained in:
Christian Grothoff 2020-01-20 12:10:44 +01:00
parent 8a4201c43b
commit 52797133a4
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
6 changed files with 69 additions and 60 deletions

View File

@ -983,7 +983,7 @@ main (int argc,
char *cfgfile = NULL; char *cfgfile = NULL;
char *loglev = NULL; char *loglev = NULL;
char *logfile = NULL; char *logfile = NULL;
int connection_close; int connection_close = GNUNET_NO;
const struct GNUNET_GETOPT_CommandLineOption options[] = { const struct GNUNET_GETOPT_CommandLineOption options[] = {
GNUNET_GETOPT_option_flag ('C', GNUNET_GETOPT_option_flag ('C',
"connection-close", "connection-close",
@ -1084,31 +1084,32 @@ main (int argc,
} }
/* initialize #internal_key_state with an RC of 1 */ /* initialize #internal_key_state with an RC of 1 */
TEH_KS_init (); if (GNUNET_OK ==
TEH_KS_init ())
/* consider unix path */
if ( (-1 == fh) &&
(NULL != serve_unixpath) )
{ {
fh = TALER_MHD_open_unix_path (serve_unixpath,
unixpath_mode);
if (-1 == fh)
return 1;
}
#if HAVE_DEVELOPER #if HAVE_DEVELOPER
if (NULL != input_filename) if (NULL != input_filename)
{ {
if (-1 != fh) ret = run_single_request ();
GNUNET_break (0 == close (fh)); }
ret = run_single_request (); else
}
else
#endif #endif
ret = run_main_loop (fh, {
argv); /* consider unix path */
if ( (-1 == fh) &&
/* release #internal_key_state */ (NULL != serve_unixpath) )
TEH_KS_free (); {
fh = TALER_MHD_open_unix_path (serve_unixpath,
unixpath_mode);
if (-1 == fh)
return 1;
}
ret = run_main_loop (fh,
argv);
}
/* release #internal_key_state */
TEH_KS_free ();
}
TALER_EXCHANGEDB_plugin_unload (TEH_plugin); TALER_EXCHANGEDB_plugin_unload (TEH_plugin);
TEH_VALIDATION_done (); TEH_VALIDATION_done ();
return (GNUNET_SYSERR == ret) ? 1 : 0; return (GNUNET_SYSERR == ret) ? 1 : 0;

View File

@ -2170,30 +2170,8 @@ handle_sigchld ()
int int
TEH_KS_loop (void) TEH_KS_loop (void)
{ {
struct GNUNET_SIGNAL_Context *sigusr1;
struct GNUNET_SIGNAL_Context *sigterm;
struct GNUNET_SIGNAL_Context *sigint;
struct GNUNET_SIGNAL_Context *sighup;
struct GNUNET_SIGNAL_Context *sigchld;
int ret; int ret;
if (0 != pipe (reload_pipe))
{
GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
"pipe");
return GNUNET_SYSERR;
}
sigusr1 = GNUNET_SIGNAL_handler_install (SIGUSR1,
&handle_sigusr1);
sigterm = GNUNET_SIGNAL_handler_install (SIGTERM,
&handle_sigterm);
sigint = GNUNET_SIGNAL_handler_install (SIGINT,
&handle_sigint);
sighup = GNUNET_SIGNAL_handler_install (SIGHUP,
&handle_sighup);
sigchld = GNUNET_SIGNAL_handler_install (SIGCHLD,
&handle_sigchld);
ret = 2; ret = 2;
while (2 == ret) while (2 == ret)
{ {
@ -2267,32 +2245,48 @@ TEH_KS_loop (void)
break; break;
} }
} }
GNUNET_SIGNAL_handler_uninstall (sigusr1);
GNUNET_SIGNAL_handler_uninstall (sigterm);
GNUNET_SIGNAL_handler_uninstall (sigint);
GNUNET_SIGNAL_handler_uninstall (sighup);
GNUNET_SIGNAL_handler_uninstall (sigchld);
GNUNET_break (0 == close (reload_pipe[0]));
GNUNET_break (0 == close (reload_pipe[1]));
return ret; return ret;
} }
static struct GNUNET_SIGNAL_Context *sigusr1;
static struct GNUNET_SIGNAL_Context *sigterm;
static struct GNUNET_SIGNAL_Context *sigint;
static struct GNUNET_SIGNAL_Context *sighup;
static struct GNUNET_SIGNAL_Context *sigchld;
/** /**
* Setup initial #internal_key_state. * Setup initial #internal_key_state.
*/ */
void int
TEH_KS_init (void) TEH_KS_init (void)
{ {
if (0 != pipe (reload_pipe))
{
GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
"pipe");
return GNUNET_SYSERR;
}
sigusr1 = GNUNET_SIGNAL_handler_install (SIGUSR1,
&handle_sigusr1);
sigterm = GNUNET_SIGNAL_handler_install (SIGTERM,
&handle_sigterm);
sigint = GNUNET_SIGNAL_handler_install (SIGINT,
&handle_sigint);
sighup = GNUNET_SIGNAL_handler_install (SIGHUP,
&handle_sighup);
sigchld = GNUNET_SIGNAL_handler_install (SIGCHLD,
&handle_sigchld);
/* no need to lock here, as we are still single-threaded */ /* no need to lock here, as we are still single-threaded */
internal_key_state = make_fresh_key_state (GNUNET_TIME_absolute_get ()); internal_key_state = make_fresh_key_state (GNUNET_TIME_absolute_get ());
if (NULL == internal_key_state) if (NULL == internal_key_state)
{ {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to setup initial key state. This exchange cannot work.\n"); "Failed to setup initial key state. This exchange cannot work.\n");
return; return GNUNET_SYSERR;
} }
internal_key_state->refcnt = 1; internal_key_state->refcnt = 1;
return GNUNET_OK;
} }
@ -2312,6 +2306,13 @@ TEH_KS_free ()
GNUNET_assert (1 == ks->refcnt); GNUNET_assert (1 == ks->refcnt);
ks->refcnt--; ks->refcnt--;
ks_free (ks); ks_free (ks);
GNUNET_SIGNAL_handler_uninstall (sigusr1);
GNUNET_SIGNAL_handler_uninstall (sigterm);
GNUNET_SIGNAL_handler_uninstall (sigint);
GNUNET_SIGNAL_handler_uninstall (sighup);
GNUNET_SIGNAL_handler_uninstall (sigchld);
GNUNET_break (0 == close (reload_pipe[0]));
GNUNET_break (0 == close (reload_pipe[1]));
} }

View File

@ -84,8 +84,10 @@ TEH_KS_release_ (const char *location,
/** /**
* Setup initial #internal_key_state. * Setup initial #internal_key_state.
*
* @return #GNUNET_OK on success
*/ */
void int
TEH_KS_init (void); TEH_KS_init (void);

View File

@ -27,7 +27,7 @@ unset XDG_CONFIG_HOME
echo -n "Launching exchange ..." echo -n "Launching exchange ..."
PREFIX= PREFIX=
# Uncomment this line to run with valgrind... # Uncomment this line to run with valgrind...
#PREFIX="valgrind --leak-check=yes --track-fds=yes --error-exitcode=1 --log-file=valgrind.%p" # PREFIX="valgrind --leak-check=yes --track-fds=yes --error-exitcode=1 --log-file=valgrind.%p"
# Setup keys. # Setup keys.
taler-exchange-keyup -c test_taler_exchange_httpd.conf || exit 1 taler-exchange-keyup -c test_taler_exchange_httpd.conf || exit 1
@ -38,7 +38,7 @@ $PREFIX taler-exchange-httpd -c test_taler_exchange_httpd.conf -i 2> test-exchan
# Give HTTP time to start # Give HTTP time to start
for n in `seq 1 20` for n in `seq 1 100`
do do
echo -n "." echo -n "."
sleep 0.1 sleep 0.1
@ -49,6 +49,9 @@ done
if [ 1 != $OK ] if [ 1 != $OK ]
then then
echo "Failed to launch exchange" echo "Failed to launch exchange"
kill -TERM $!
wait $!
echo Process status: $?
exit 77 exit 77
fi fi
echo " DONE" echo " DONE"

View File

@ -7405,8 +7405,7 @@ libtaler_plugin_exchangedb_postgres_done (void *cls)
/* If we launched a session for the main thread, /* If we launched a session for the main thread,
kill it here before we unload */ kill it here before we unload */
if (NULL != pg->main_session) db_conn_destroy (pg->main_session);
db_conn_destroy (pg->main_session);
GNUNET_free (pg->connection_cfg_str); GNUNET_free (pg->connection_cfg_str);
GNUNET_free (pg->sql_dir); GNUNET_free (pg->sql_dir);
GNUNET_free (pg->currency); GNUNET_free (pg->currency);

View File

@ -485,7 +485,10 @@ load_language (struct TALER_MHD_Legal *legal,
lang); lang);
d = opendir (dname); d = opendir (dname);
if (NULL == d) if (NULL == d)
{
GNUNET_free (dname);
return; return;
}
for (struct dirent *de = readdir (d); for (struct dirent *de = readdir (d);
NULL != de; NULL != de;
de = readdir (d)) de = readdir (d))
@ -497,7 +500,7 @@ load_language (struct TALER_MHD_Legal *legal,
load_terms (legal, path, lang, fn); load_terms (legal, path, lang, fn);
} }
closedir (d); closedir (d);
free (dname); GNUNET_free (dname);
} }