# HG changeset patch # User Sebastien Decugis # Date 1295415314 -32400 # Node ID f83d9878bf66094520382e85cc693280f874d9a1 # Parent a0209539c044234b4b2ab5d46f8024d248a01feb Fixed in case of termination of several modules (before initialization completed) diff -r a0209539c044 -r f83d9878bf66 libfdcore/config.c --- a/libfdcore/config.c Wed Jan 19 11:11:23 2011 +0900 +++ b/libfdcore/config.c Wed Jan 19 14:35:14 2011 +0900 @@ -456,6 +456,9 @@ { TRACE_ENTRY(); + if (!fd_g_config) + return 0; + /* Free the TLS parameters */ gnutls_priority_deinit(fd_g_config->cnf_sec_data.prio_cache); gnutls_dh_params_deinit(fd_g_config->cnf_sec_data.dh_cache); diff -r a0209539c044 -r f83d9878bf66 libfdcore/core.c --- a/libfdcore/core.c Wed Jan 19 11:11:23 2011 +0900 +++ b/libfdcore/core.c Wed Jan 19 14:35:14 2011 +0900 @@ -38,8 +38,8 @@ #include /* The static configuration structure */ -static struct fd_config conf; -struct fd_config * fd_g_config = &conf; +static struct fd_config g_conf; +struct fd_config * fd_g_config = NULL; /* gcrypt functions to support posix threads */ GCRY_THREAD_OPTION_PTHREAD_IMPL; @@ -61,11 +61,18 @@ /* Thread that process incoming events on the main queue -- and terminates the framework when requested */ static pthread_t core_runner = (pthread_t)NULL; +enum core_mode { + CORE_MODE_EVENTS, + CORE_MODE_IMMEDIATE +}; static void * core_runner_thread(void * arg) { fd_log_threadname("Core Runner"); + if (arg && (*(int *)arg == CORE_MODE_IMMEDIATE)) + goto end; + /* Handle events incoming on the main event queue */ while (1) { int code; size_t sz; void * data; @@ -160,8 +167,6 @@ { int ret; - memset(fd_g_config, 0, sizeof(struct fd_config)); - /* Initialize the library -- must come first since it initializes the debug facility */ ret = fd_libproto_init(); if (ret != 0) { @@ -186,6 +191,8 @@ } /* Initialize the config with default values */ + memset(&g_conf, 0, sizeof(struct fd_config)); + fd_g_config = &g_conf; CHECK_FCT( fd_conf_init() ); /* Add definitions of the base protocol */ @@ -268,8 +275,14 @@ /* Initialize shutdown of the framework. This is not blocking. */ int fd_core_shutdown(void) { - /* Signal the framework to terminate */ - CHECK_FCT( fd_event_send(fd_g_config->cnf_main_ev, FDEV_TERMINATE, 0, NULL) ); + if (core_runner != (pthread_t)NULL) { + /* Signal the framework to terminate */ + CHECK_FCT( fd_event_send(fd_g_config->cnf_main_ev, FDEV_TERMINATE, 0, NULL) ); + } else { + /* The framework was maybe not fully initialized (ex: tests) */ + enum core_mode arg = CORE_MODE_IMMEDIATE; + (void) core_runner_thread(&arg); + } return 0; } @@ -281,11 +294,13 @@ int ret; void * th_ret = NULL; - /* Just wait for core_runner_thread to complete and return gracefully */ - ret = pthread_join(core_runner, &th_ret); - if (ret != 0) { - fprintf(stderr, "Unable to wait for main framework thread termination: %s\n", strerror(ret)); - return ret; + if (core_runner != (pthread_t)NULL) { + /* Just wait for core_runner_thread to complete and return gracefully */ + ret = pthread_join(core_runner, &th_ret); + if (ret != 0) { + fprintf(stderr, "Unable to wait for main framework thread termination: %s\n", strerror(ret)); + return ret; + } } return 0; diff -r a0209539c044 -r f83d9878bf66 libfdcore/p_expiry.c --- a/libfdcore/p_expiry.c Wed Jan 19 11:11:23 2011 +0900 +++ b/libfdcore/p_expiry.c Wed Jan 19 14:35:14 2011 +0900 @@ -38,8 +38,8 @@ /* Delay for garbage collection of expired peers, in seconds */ #define GC_TIME 120 -static pthread_t exp_thr; -static pthread_t gc_thr; +static pthread_t exp_thr = (pthread_t)NULL; +static pthread_t gc_thr = (pthread_t)NULL; static struct fd_list exp_list = FD_LIST_INITIALIZER( exp_list ); static pthread_cond_t exp_cnd = PTHREAD_COND_INITIALIZER; static pthread_mutex_t exp_mtx = PTHREAD_MUTEX_INITIALIZER; diff -r a0209539c044 -r f83d9878bf66 libfdcore/queues.c --- a/libfdcore/queues.c Wed Jan 19 11:11:23 2011 +0900 +++ b/libfdcore/queues.c Wed Jan 19 14:35:14 2011 +0900 @@ -59,6 +59,10 @@ TRACE_ENTRY("%p", queue); /* Note : the threads that post into this queue should already been stopped before this !!! */ + + CHECK_PARAMS(queue); + if (*queue == NULL) + return 0; /* the queue was not already initialized */ /* Empty all contents */ while (1) { diff -r a0209539c044 -r f83d9878bf66 libfdcore/routing_dispatch.c --- a/libfdcore/routing_dispatch.c Wed Jan 19 11:11:23 2011 +0900 +++ b/libfdcore/routing_dispatch.c Wed Jan 19 14:35:14 2011 +0900 @@ -972,11 +972,11 @@ static pthread_mutex_t order_lock = PTHREAD_MUTEX_INITIALIZER; /* Threads report their status */ -enum thread_state { INITIAL = 0, RUNNING = 1, TERMINATED = 2 }; +enum thread_state { NOTRUNNING = 0, RUNNING = 1 }; static void cleanup_state(void * state_loc) { if (state_loc) - *(enum thread_state *)state_loc = TERMINATED; + *(enum thread_state *)state_loc = NOTRUNNING; } /* This is the common thread code (same for routing and dispatching) */ @@ -1079,10 +1079,10 @@ /* Later: make this more dynamic */ static pthread_t rt_out = (pthread_t)NULL; -static enum thread_state out_state = INITIAL; +static enum thread_state out_state = NOTRUNNING; static pthread_t rt_in = (pthread_t)NULL; -static enum thread_state in_state = INITIAL; +static enum thread_state in_state = NOTRUNNING; /* Initialize the routing and dispatch threads */ int fd_rtdisp_init(void) @@ -1090,8 +1090,8 @@ int i; /* Prepare the array for dispatch */ + CHECK_MALLOC( disp_state = calloc(fd_g_config->cnf_dispthr, sizeof(enum thread_state)) ); CHECK_MALLOC( dispatch = calloc(fd_g_config->cnf_dispthr, sizeof(pthread_t)) ); - CHECK_MALLOC( disp_state = calloc(fd_g_config->cnf_dispthr, sizeof(enum thread_state)) ); /* Create the threads */ for (i=0; i < fd_g_config->cnf_dispthr; i++) { @@ -1125,7 +1125,7 @@ /* Wait for a second for the thread to complete, by monitoring my_state */ fd_cpu_flush_cache(); - if (*st != TERMINATED) { + if (*st != NOTRUNNING) { TRACE_DEBUG(INFO, "Waiting for the %s thread to have a chance to terminate", th_name); do { struct timespec ts, ts_final; @@ -1136,7 +1136,8 @@ ts_final.tv_nsec = ts.tv_nsec; while (TS_IS_INFERIOR( &ts, &ts_final )) { - if (*st == TERMINATED) + fd_cpu_flush_cache(); + if (*st == NOTRUNNING) break; usleep(100000); @@ -1170,9 +1171,17 @@ /* Destroy the local queue */ CHECK_FCT_DO( fd_queues_fini(&fd_g_local), /* ignore */); - /* Stop the Dispatch thread */ - for (i=0; i < fd_g_config->cnf_dispthr; i++) { - stop_thread_delayed(&disp_state[i], &dispatch[i], "Dispatching"); + /* Stop the Dispatch threads */ + if (dispatch != NULL) { + for (i=0; i < fd_g_config->cnf_dispthr; i++) { + stop_thread_delayed(&disp_state[i], &dispatch[i], "Dispatching"); + } + free(dispatch); + dispatch = NULL; + } + if (disp_state != NULL) { + free(disp_state); + disp_state = NULL; } return 0; diff -r a0209539c044 -r f83d9878bf66 libfdcore/server.c --- a/libfdcore/server.c Wed Jan 19 11:11:23 2011 +0900 +++ b/libfdcore/server.c Wed Jan 19 14:35:14 2011 +0900 @@ -35,10 +35,10 @@ #include "fdcore-internal.h" -/* Server (listening) part of the daemon */ +/* Server (listening) part of the framework */ -struct fd_list FD_SERVERS = FD_LIST_INITIALIZER(FD_SERVERS); /* The list of all server objects */ -/* We don't need to protect this list, it is only accessed from the main daemon thread. */ +static struct fd_list FD_SERVERS = FD_LIST_INITIALIZER(FD_SERVERS); /* The list of all server objects */ +/* We don't need to protect this list, it is only accessed from the main framework thread. */ /* Servers information */ struct server { @@ -82,7 +82,7 @@ ((s->status == 2) ? "Thread terminated" : "Thread status unknown"))); /* Dump the client list of this server */ - (void) pthread_mutex_lock(&s->clients_mtx); + CHECK_POSIX_DO( pthread_mutex_lock(&s->clients_mtx), ); for (cli = s->clients.next; cli != &s->clients; cli = cli->next) { struct client * c = (struct client *)cli; char bufts[128]; @@ -90,7 +90,7 @@ fd_cnx_getid(c->conn), fd_log_time(&c->ts, bufts, sizeof(bufts))); } - (void) pthread_mutex_unlock(&s->clients_mtx); + CHECK_POSIX_DO( pthread_mutex_unlock(&s->clients_mtx), ); } } diff -r a0209539c044 -r f83d9878bf66 libfdproto/messages.c --- a/libfdproto/messages.c Wed Jan 19 11:11:23 2011 +0900 +++ b/libfdproto/messages.c Wed Jan 19 14:35:14 2011 +0900 @@ -1108,8 +1108,8 @@ /******************* End-to-end counter *********************/ -uint32_t fd_eteid; -pthread_mutex_t fd_eteid_lck = PTHREAD_MUTEX_INITIALIZER; +static uint32_t fd_eteid; +static pthread_mutex_t fd_eteid_lck = PTHREAD_MUTEX_INITIALIZER; void fd_msg_eteid_init(void) { diff -r a0209539c044 -r f83d9878bf66 libfdproto/sessions.c --- a/libfdproto/sessions.c Wed Jan 19 11:11:23 2011 +0900 +++ b/libfdproto/sessions.c Wed Jan 19 14:35:14 2011 +0900 @@ -121,7 +121,7 @@ static struct fd_list exp_sentinel = FD_LIST_INITIALIZER(exp_sentinel); /* list of sessions ordered by their timeout date */ static pthread_mutex_t exp_lock = PTHREAD_MUTEX_INITIALIZER; /* lock protecting the list. */ static pthread_cond_t exp_cond = PTHREAD_COND_INITIALIZER; /* condvar used by the expiry mecahinsm. */ -static pthread_t exp_thr; /* The expiry thread that handles cleanup of expired sessions */ +static pthread_t exp_thr = (pthread_t)NULL; /* The expiry thread that handles cleanup of expired sessions */ /* Hierarchy of the locks, to avoid deadlocks: * hash lock > state lock > expiry lock