Mercurial > hg > freeDiameter
diff libfdcore/core.c @ 1182:cc96a4dfb3d1
Early shutdown situation: detect the race condition and delay the shutdown in freeDiameterd. Alternative would be to initialize in a separate thread that we can cancel before calling shutdown.
author | Sebastien Decugis <sdecugis@freediameter.net> |
---|---|
date | Thu, 06 Jun 2013 11:25:23 +0800 |
parents | eaa92af9e46d |
children | 6a1042d8075b |
line wrap: on
line diff
--- a/libfdcore/core.c Wed Jun 05 19:22:26 2013 +0800 +++ b/libfdcore/core.c Thu Jun 06 11:25:23 2013 +0800 @@ -227,8 +227,10 @@ return 0; } +static pthread_mutex_t core_lock = PTHREAD_MUTEX_INITIALIZER; + /* Parse the freeDiameter.conf configuration file, load the extensions */ -int fd_core_parseconf(const char * conffile) +static int fd_core_parseconf_int(const char * conffile) { char * buf = NULL, *b; size_t len = 0, offset=0; @@ -273,6 +275,16 @@ return 0; } +int fd_core_parseconf(const char * conffile) +{ + int ret; + CHECK_POSIX( pthread_mutex_lock(&core_lock) ); + ret = fd_core_parseconf_int(conffile); + CHECK_POSIX( pthread_mutex_unlock(&core_lock) ); + return ret; +} + + /* For threads that would need to wait complete start of the framework (ex: in extensions) */ int fd_core_waitstartcomplete(void) { @@ -282,7 +294,7 @@ } /* Start the server & client threads */ -int fd_core_start(void) +static int fd_core_start_int(void) { /* Start server threads */ CHECK_FCT( fd_servers_start() ); @@ -300,6 +312,14 @@ return 0; } +int fd_core_start(void) +{ + int ret; + CHECK_POSIX( pthread_mutex_lock(&core_lock) ); + ret = fd_core_start_int(); + CHECK_POSIX( pthread_mutex_unlock(&core_lock) ); + return ret; +} /* Initialize shutdown of the framework. This is not blocking. */ int fd_core_shutdown(void) @@ -307,8 +327,15 @@ enum core_state cur_state = core_state_get(); if (cur_state < CORE_RUNNING) { + /* Calling application must make sure the initialization is not ongoing in a separate thread... */ + if (pthread_mutex_lock(&core_lock) != 0) { + /* This function must not be called asynchronously from fd_core_parseconf / fd_core_start ! Please review your main app design */ + ASSERT(0); + return EINVAL; + } core_shutdown(); core_state_set(CORE_TERM); + pthread_mutex_unlock(&core_lock); } else if (cur_state == CORE_RUNNING) { core_state_set(CORE_SHUTDOWN); CHECK_FCT( fd_event_send(fd_g_config->cnf_main_ev, FDEV_TERMINATE, 0, NULL) );