From 8adacfc236c16e02ed5f0b7c17d565b8f50bd4b7 Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Thu, 12 May 2016 09:23:19 +0200 Subject: irmd: cleanup improved cleanup when killing the IRMd. --- src/irmd/main.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 115 insertions(+), 12 deletions(-) diff --git a/src/irmd/main.c b/src/irmd/main.c index b660511c..aba69224 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -82,7 +82,7 @@ struct reg_name_entry { char * req_ap_name; char * req_ae_name; int response; - bool flow_arrived; + int flow_arrived; pthread_cond_t acc_signal; pthread_mutex_t acc_lock; @@ -121,6 +121,9 @@ struct irm { pthread_t * threadpool; pthread_mutex_t r_lock; + + bool shutdown; + pthread_mutex_t s_lock; } * instance = NULL; static struct port_map_entry * port_map_entry_create() @@ -278,7 +281,7 @@ static struct reg_name_entry * reg_name_entry_create() e->accept = false; e->req_ap_name = NULL; e->req_ae_name = NULL; - e->flow_arrived = false; + e->flow_arrived = -1; if (pthread_cond_init(&e->acc_signal, NULL)) { free(e); @@ -313,6 +316,14 @@ static int reg_name_entry_destroy(struct reg_name_entry * e) if (e == NULL) return 0; + if (e->accept) { + pthread_mutex_lock(&e->acc_lock); + e->flow_arrived = -2; + pthread_mutex_unlock(&e->acc_lock); + pthread_cond_broadcast(&e->acc_signal); + sched_yield(); + } + free(e->name); instance_name_destroy(e->api); @@ -323,6 +334,8 @@ static int reg_name_entry_destroy(struct reg_name_entry * e) free(e); + e = NULL; + return 0; } @@ -397,6 +410,14 @@ static pid_t create_ipcp(char * ap_name, pid_t pid; struct ipcp_entry * tmp = NULL; + pthread_mutex_lock(&instance->s_lock); + if (instance->shutdown) { + pthread_mutex_unlock(&instance->s_lock); + return -1; + } + pthread_mutex_unlock(&instance->s_lock); + + pid = ipcp_create(ap_name, ipcp_type); if (pid == -1) { LOG_ERR("Failed to create IPCP."); @@ -476,6 +497,13 @@ static int bootstrap_ipcp(instance_name_t * api, { struct ipcp_entry * entry = NULL; + pthread_mutex_lock(&instance->s_lock); + if (instance->shutdown) { + pthread_mutex_unlock(&instance->s_lock); + return -1; + } + pthread_mutex_unlock(&instance->s_lock); + pthread_mutex_lock(&instance->r_lock); if (api->id == 0) @@ -525,6 +553,13 @@ static int enroll_ipcp(instance_name_t * api, ssize_t n_1_difs_size = 0; struct ipcp_entry * entry = NULL; + pthread_mutex_lock(&instance->s_lock); + if (instance->shutdown) { + pthread_mutex_unlock(&instance->s_lock); + return -1; + } + pthread_mutex_unlock(&instance->s_lock); + pthread_mutex_lock(&instance->r_lock); entry = get_ipcp_entry_by_name(api); @@ -580,6 +615,13 @@ static int reg_ipcp(instance_name_t * api, char ** difs, size_t difs_size) { + pthread_mutex_lock(&instance->s_lock); + if (instance->shutdown) { + pthread_mutex_unlock(&instance->s_lock); + return -1; + } + pthread_mutex_unlock(&instance->s_lock); + if (ipcp_reg(api->id, difs, difs_size)) { LOG_ERR("Could not register IPCP to N-1 DIF(s)."); return -1; @@ -614,6 +656,12 @@ static int ap_reg(char * ap_name, instance_name_t * api = NULL; instance_name_t * ipcpi = NULL; + pthread_mutex_lock(&instance->s_lock); + if (instance->shutdown) { + pthread_mutex_unlock(&instance->s_lock); + return -1; + } + pthread_mutex_unlock(&instance->s_lock); pthread_mutex_lock(&instance->r_lock); @@ -742,6 +790,7 @@ static int ap_unreg(char * ap_name, } } + /* FIXME: check if name is not registered in any DIF before removing */ reg_name_entry_del_name(rne->name); pthread_mutex_unlock(&instance->r_lock); @@ -756,6 +805,12 @@ static struct port_map_entry * flow_accept(pid_t pid, struct port_map_entry * pme; struct reg_name_entry * rne = NULL; + pthread_mutex_lock(&instance->s_lock); + if (instance->shutdown) { + pthread_mutex_unlock(&instance->s_lock); + return NULL; + } + pthread_mutex_unlock(&instance->s_lock); pthread_mutex_lock(&instance->r_lock); rne = get_reg_name_entry_by_id(pid); @@ -771,15 +826,30 @@ static struct port_map_entry * flow_accept(pid_t pid, } rne->accept = true; - rne->flow_arrived = false; + rne->flow_arrived = -1; pthread_mutex_unlock(&instance->r_lock); + pthread_mutex_lock(&rne->acc_lock); + pthread_cleanup_push((void(*)(void *))pthread_mutex_unlock, + (void*) &rne->acc_lock); - while (!rne->flow_arrived) + while (rne->flow_arrived == -1) pthread_cond_wait(&rne->acc_signal, &rne->acc_lock); pthread_mutex_unlock(&rne->acc_lock); + pthread_cleanup_pop(0); + + pthread_mutex_lock(&rne->acc_lock); + + /* ap with pending accept being unregistered */ + if (rne->flow_arrived == -2 ) { + pthread_mutex_unlock(&rne->acc_lock); + return NULL; + } + + pthread_mutex_unlock(&rne->acc_lock); + pthread_mutex_lock(&instance->r_lock); pme = get_port_map_entry_n(pid); @@ -805,6 +875,13 @@ static int flow_alloc_resp(pid_t n_pid, struct port_map_entry * pme = NULL; struct reg_name_entry * rne = NULL; + pthread_mutex_lock(&instance->s_lock); + if (instance->shutdown) { + pthread_mutex_unlock(&instance->s_lock); + return -1; + } + pthread_mutex_unlock(&instance->s_lock); + pthread_mutex_lock(&instance->r_lock); rne = get_reg_name_entry_by_id(n_pid); @@ -826,7 +903,7 @@ static int flow_alloc_resp(pid_t n_pid, */ rne->accept = false; - rne->flow_arrived = false; + rne->flow_arrived = -1; if (!response) { pme = get_port_map_entry(port_id); @@ -850,6 +927,13 @@ static struct port_map_entry * flow_alloc(pid_t pid, struct port_map_entry * pme; instance_name_t * ipcp; + pthread_mutex_lock(&instance->s_lock); + if (instance->shutdown) { + pthread_mutex_unlock(&instance->s_lock); + return NULL; + } + pthread_mutex_unlock(&instance->s_lock); + pme = port_map_entry_create(); if (pme == NULL) { LOG_ERR("Failed malloc of port_map_entry."); @@ -901,6 +985,13 @@ static int flow_alloc_res(int port_id) { struct port_map_entry * e; + pthread_mutex_lock(&instance->s_lock); + if (instance->shutdown) { + pthread_mutex_unlock(&instance->s_lock); + return -1; + } + pthread_mutex_unlock(&instance->s_lock); + pthread_mutex_lock(&instance->r_lock); e = get_port_map_entry(port_id); @@ -981,6 +1072,13 @@ static struct port_map_entry * flow_req_arr(pid_t pid, struct reg_name_entry * rne; struct port_map_entry * pme; + pthread_mutex_lock(&instance->s_lock); + if (instance->shutdown) { + pthread_mutex_unlock(&instance->s_lock); + return NULL; + } + pthread_mutex_unlock(&instance->s_lock); + pme = malloc(sizeof(*pme)); if (pme == NULL) { LOG_ERR("Failed malloc of port_map_entry."); @@ -1004,14 +1102,14 @@ static struct port_map_entry * flow_req_arr(pid_t pid, pme->n_pid = rne->api->id; - list_add(&pme->next, &instance->port_map); - rne->req_ap_name = strdup(ap_name); rne->req_ae_name = strdup(ae_name); + list_add(&pme->next, &instance->port_map); + pthread_mutex_lock(&rne->acc_lock); - rne->flow_arrived = true; + rne->flow_arrived = 0; if (pthread_cond_signal(&rne->acc_signal)) LOG_ERR("Failed to send signal."); @@ -1020,7 +1118,6 @@ static struct port_map_entry * flow_req_arr(pid_t pid, pthread_mutex_unlock(&instance->r_lock); - return pme; } @@ -1076,7 +1173,7 @@ static int flow_dealloc_ipcp(int port_id) return 0; } -static void irm_destroy(struct irm * irm) +static void irm_destroy(struct irm * irm) { struct list_head * h; struct list_head * t; @@ -1084,6 +1181,10 @@ static void irm_destroy(struct irm * irm) if (irm == NULL) return; + pthread_mutex_lock(&irm->s_lock); + instance->shutdown = true; + pthread_mutex_unlock(&irm->s_lock); + if (irm->threadpool != NULL) free(irm->threadpool); @@ -1100,7 +1201,7 @@ static void irm_destroy(struct irm * irm) struct reg_name_entry, next); list_del(&e->next); - free(e); + reg_name_entry_destroy(e); } list_for_each_safe(h, t, &irm->port_map) { @@ -1358,7 +1459,9 @@ static struct irm * irm_create() return NULL; } - if (pthread_mutex_init(&i->r_lock, NULL)) { + i->shutdown = false; + + if (pthread_mutex_init(&i->s_lock, NULL)) { irm_destroy(i); return NULL; } -- cgit v1.2.3