From f8e230049143412ac424d4cbfd4ca95b6c7f64e1 Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Wed, 28 Dec 2016 09:51:08 +0100 Subject: irmd: Hide reg_entry internal lock --- src/irmd/main.c | 70 +++++++++-------------------------------------------- src/irmd/registry.c | 51 ++++++++++++++++++++++++++++++++++++++ src/irmd/registry.h | 60 +++++++++++++++++++++++++-------------------- 3 files changed, 97 insertions(+), 84 deletions(-) diff --git a/src/irmd/main.c b/src/irmd/main.c index 5ba61fa0..c42f2d3c 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -973,11 +973,8 @@ static struct irm_flow * flow_accept(pid_t api, char ** dst_ae_name) struct str_el * s = list_entry(p, struct str_el, next); LOG_DBG(" %s", s->str); re = registry_get_entry(&irmd->registry, s->str); - if (re != NULL) { - pthread_mutex_lock(&re->state_lock); + if (re != NULL) reg_entry_add_api(re, api); - pthread_mutex_unlock(&re->state_lock); - } } pthread_rwlock_unlock(&irmd->reg_lock); @@ -1015,17 +1012,12 @@ static struct irm_flow * flow_accept(pid_t api, char ** dst_ae_name) pthread_mutex_unlock(&e->state_lock); - pthread_mutex_lock(&re->state_lock); - - if (re->state != REG_NAME_FLOW_ARRIVED) { - pthread_mutex_unlock(&re->state_lock); + if (reg_entry_get_state(re) != REG_NAME_FLOW_ARRIVED) { pthread_rwlock_unlock(&irmd->reg_lock); pthread_rwlock_unlock(&irmd->state_lock); return NULL; } - pthread_mutex_unlock(&re->state_lock); pthread_rwlock_unlock(&irmd->reg_lock); - pthread_rwlock_rdlock(&irmd->flows_lock); f = get_irm_flow_n(api); @@ -1085,22 +1077,16 @@ static int flow_alloc_resp(pid_t n_api, return -1; } - pthread_mutex_lock(&re->state_lock); - - if (re->state != REG_NAME_FLOW_ARRIVED) { - pthread_mutex_unlock(&re->state_lock); + if (reg_entry_get_state(re) != REG_NAME_FLOW_ARRIVED) { pthread_rwlock_unlock(&irmd->reg_lock); pthread_rwlock_unlock(&irmd->state_lock); LOG_ERR("Name %s has no pending flow request.", re->name); return -1; } - pthread_mutex_unlock(&re->state_lock); - registry_del_api(&irmd->registry, n_api); pthread_rwlock_unlock(&irmd->reg_lock); - pthread_rwlock_wrlock(&irmd->flows_lock); f = get_irm_flow(port_id); @@ -1335,8 +1321,6 @@ static struct irm_flow * flow_req_arr(pid_t api, struct api_entry * e = NULL; struct irm_flow * f = NULL; - enum reg_name_state state; - struct pid_el * c_api; pid_t h_api = -1; int port_id = -1; @@ -1355,11 +1339,7 @@ static struct irm_flow * flow_req_arr(pid_t api, return NULL; } - pthread_mutex_lock(&re->state_lock); - state = re->state; - pthread_mutex_unlock(&re->state_lock); - - switch (state) { + switch (reg_entry_get_state(re)) { case REG_NAME_IDLE: pthread_rwlock_unlock(&irmd->reg_lock); pthread_rwlock_unlock(&irmd->state_lock); @@ -1373,16 +1353,12 @@ static struct irm_flow * flow_req_arr(pid_t api, return NULL; } - pthread_mutex_lock(&re->state_lock); - - re->state = REG_NAME_AUTO_EXEC; + reg_entry_set_state(re, REG_NAME_AUTO_EXEC); a = apn_table_get_by_apn(&irmd->apn_table, reg_entry_get_apn(re)); - pthread_mutex_unlock(&re->state_lock); + if (a == NULL || (c_api->pid = auto_execute(a->argv)) < 0) { - pthread_mutex_lock(&re->state_lock); - re->state = REG_NAME_AUTO_ACCEPT; - pthread_mutex_unlock(&re->state_lock); + reg_entry_set_state(re, REG_NAME_AUTO_ACCEPT); pthread_rwlock_unlock(&irmd->reg_lock); pthread_rwlock_unlock(&irmd->state_lock); LOG_ERR("Could not get start apn for reg_entry %s.", @@ -1396,32 +1372,19 @@ static struct irm_flow * flow_req_arr(pid_t api, pthread_rwlock_unlock(&irmd->reg_lock); pthread_rwlock_unlock(&irmd->state_lock); - pthread_mutex_lock(&re->state_lock); - - while (re->state == REG_NAME_AUTO_EXEC) - pthread_cond_wait(&re->state_cond, &re->state_lock); - - pthread_mutex_unlock(&re->state_lock); + reg_entry_leave_state(re, REG_NAME_AUTO_EXEC); pthread_rwlock_rdlock(&irmd->state_lock); pthread_rwlock_rdlock(&irmd->reg_lock); - pthread_mutex_lock(&re->state_lock); - - if (re->state == REG_NAME_DESTROY) { - re->state = REG_NAME_NULL; - pthread_mutex_unlock(&re->state_lock); + if (reg_entry_get_state(re) == REG_NAME_DESTROY) { + reg_entry_set_state(re, REG_NAME_NULL); pthread_rwlock_unlock(&irmd->reg_lock); pthread_rwlock_unlock(&irmd->state_lock); return NULL; } - - pthread_mutex_unlock(&re->state_lock); - case REG_NAME_FLOW_ACCEPT: - pthread_mutex_lock(&re->state_lock); h_api = reg_entry_get_api(re); - pthread_mutex_unlock(&re->state_lock); if (h_api == -1) { pthread_rwlock_unlock(&irmd->reg_lock); pthread_rwlock_unlock(&irmd->state_lock); @@ -1459,14 +1422,10 @@ static struct irm_flow * flow_req_arr(pid_t api, list_add(&f->next, &irmd->irm_flows); pthread_rwlock_unlock(&irmd->flows_lock); - pthread_rwlock_rdlock(&irmd->reg_lock); - pthread_mutex_lock(&re->state_lock); re->req_ae_name = ae_name; - re->state = REG_NAME_FLOW_ARRIVED; - - pthread_mutex_unlock(&re->state_lock); + reg_entry_set_state(re, REG_NAME_FLOW_ARRIVED); e = api_table_get(&irmd->api_table, h_api); if (e == NULL) { @@ -1487,12 +1446,7 @@ static struct irm_flow * flow_req_arr(pid_t api, pthread_rwlock_unlock(&irmd->reg_lock); pthread_rwlock_unlock(&irmd->state_lock); - pthread_mutex_lock(&re->state_lock); - - while (re->state == REG_NAME_FLOW_ARRIVED) - pthread_cond_wait(&re->state_cond, &re->state_lock); - - pthread_mutex_unlock(&re->state_lock); + reg_entry_leave_state(re, REG_NAME_FLOW_ARRIVED); return f; } diff --git a/src/irmd/registry.c b/src/irmd/registry.c index 61d562fc..34d0a921 100644 --- a/src/irmd/registry.c +++ b/src/irmd/registry.c @@ -278,6 +278,9 @@ int reg_entry_add_api(struct reg_entry * e, pid_t api) return -ENOMEM; i->pid = api; + + pthread_mutex_lock(&e->state_lock); + list_add(&i->next, &e->reg_apis); if (e->state == REG_NAME_IDLE || @@ -287,6 +290,8 @@ int reg_entry_add_api(struct reg_entry * e, pid_t api) pthread_cond_signal(&e->state_cond); } + pthread_mutex_unlock(&e->state_lock); + return 0; } @@ -329,6 +334,52 @@ pid_t reg_entry_get_api(struct reg_entry * e) return list_first_entry(&e->reg_apis, struct pid_el, next)->pid; } +enum reg_name_state reg_entry_get_state(struct reg_entry * e) +{ + enum reg_name_state state; + + if (e == NULL) + return REG_NAME_NULL; + + pthread_mutex_lock(&e->state_lock); + + state = e->state; + + pthread_mutex_unlock(&e->state_lock); + + return state; +} + +int reg_entry_set_state(struct reg_entry * e, enum reg_name_state state) +{ + if (state == REG_NAME_DESTROY) + return -EPERM; + + pthread_mutex_lock(&e->state_lock); + + e->state = state; + pthread_cond_broadcast(&e->state_cond); + + pthread_mutex_unlock(&e->state_lock); + + return 0; +} + +int reg_entry_leave_state(struct reg_entry * e, enum reg_name_state state) +{ + if (e == NULL || state == REG_NAME_DESTROY) + return -EINVAL; + + pthread_mutex_lock(&e->state_lock); + + while (e->state == state) + pthread_cond_wait(&e->state_cond, &e->state_lock); + + pthread_mutex_unlock(&e->state_lock); + + return 0; +} + struct reg_entry * registry_get_entry(struct list_head * registry, char * name) { diff --git a/src/irmd/registry.h b/src/irmd/registry.h index f0da9267..1cb1d921 100644 --- a/src/irmd/registry.h +++ b/src/irmd/registry.h @@ -67,46 +67,54 @@ struct reg_entry { pthread_mutex_t state_lock; }; -int reg_entry_add_apn(struct reg_entry * e, - struct apn_entry * a); +int reg_entry_add_apn(struct reg_entry * e, + struct apn_entry * a); -void reg_entry_del_apn(struct reg_entry * e, - char * apn); +void reg_entry_del_apn(struct reg_entry * e, + char * apn); -char * reg_entry_get_apn(struct reg_entry * e); +char * reg_entry_get_apn(struct reg_entry * e); -int reg_entry_add_api(struct reg_entry * e, - pid_t api); +int reg_entry_add_api(struct reg_entry * e, + pid_t api); -void reg_entry_del_api(struct reg_entry * e, - pid_t api); +void reg_entry_del_api(struct reg_entry * e, + pid_t api); -pid_t reg_entry_get_api(struct reg_entry * e); +pid_t reg_entry_get_api(struct reg_entry * e); -struct reg_entry * registry_add_name(struct list_head * registry, - char * name); +enum reg_name_state reg_entry_get_state(struct reg_entry * e); -void registry_del_name(struct list_head * registry, - char * name); +int reg_entry_set_state(struct reg_entry * e, + enum reg_name_state state); -void registry_del_api(struct list_head * registry, - pid_t api); +int reg_entry_leave_state(struct reg_entry * e, + enum reg_name_state state); -void registry_sanitize_apis(struct list_head * registry); +struct reg_entry * registry_add_name(struct list_head * registry, + char * name); -struct reg_entry * registry_get_entry(struct list_head * registry, +void registry_del_name(struct list_head * registry, char * name); -int registry_add_name_to_dif(struct list_head * registry, - char * name, - char * dif_name, - enum ipcp_type type); +void registry_del_api(struct list_head * registry, + pid_t api); + +void registry_sanitize_apis(struct list_head * registry); + +struct reg_entry * registry_get_entry(struct list_head * registry, + char * name); + +int registry_add_name_to_dif(struct list_head * registry, + char * name, + char * dif_name, + enum ipcp_type type); -void registry_del_name_from_dif(struct list_head * registry, - char * name, - char * dif_name); +void registry_del_name_from_dif(struct list_head * registry, + char * name, + char * dif_name); -void registry_destroy(struct list_head * registry); +void registry_destroy(struct list_head * registry); #endif /* OUROBOROS_IRMD_REGISTRY_H */ -- cgit v1.2.3