From f8e230049143412ac424d4cbfd4ca95b6c7f64e1 Mon Sep 17 00:00:00 2001
From: dimitri staessens <dimitri.staessens@intec.ugent.be>
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