diff options
author | dimitri staessens <dimitri.staessens@intec.ugent.be> | 2016-07-15 15:49:23 +0200 |
---|---|---|
committer | dimitri staessens <dimitri.staessens@intec.ugent.be> | 2016-07-15 15:49:23 +0200 |
commit | e14d0da88d4f3fcd0c19c231b59d31189c4d71ad (patch) | |
tree | 936e0f4857a48a4be17087c2d32b754b09433747 | |
parent | 71956f22abec7bb15f6bfc52b4168ff85499eea1 (diff) | |
download | ouroboros-e14d0da88d4f3fcd0c19c231b59d31189c4d71ad.tar.gz ouroboros-e14d0da88d4f3fcd0c19c231b59d31189c4d71ad.zip |
irmd: Fix accessing reg_api struct after destroy
The destroy now only frees after all threads stopped using the object.
Also fixes a SEGV when trying to allocate a flow to a remote name.
-rw-r--r-- | src/irmd/main.c | 30 | ||||
-rw-r--r-- | src/irmd/registry.c | 49 | ||||
-rw-r--r-- | src/irmd/registry.h | 2 |
3 files changed, 45 insertions, 36 deletions
diff --git a/src/irmd/main.c b/src/irmd/main.c index 1da4b310..625c28c8 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -247,6 +247,36 @@ static pid_t get_ipcp_by_dst_name(char * dst_name) struct list_head * pos = NULL; char * dif_name = registry_get_dif_for_dst(&instance->registry, dst_name); + if (dif_name == NULL) { + list_for_each(pos, &instance->ipcps) { + struct ipcp_entry * e = + list_entry(pos, struct ipcp_entry, next); + if (e->type == IPCP_NORMAL) { + dif_name = e->dif_name; + break; + } + } + + list_for_each(pos, &instance->ipcps) { + struct ipcp_entry * e = + list_entry(pos, struct ipcp_entry, next); + if (e->type == IPCP_SHIM_ETH_LLC) { + dif_name = e->dif_name; + break; + } + } + + + list_for_each(pos, &instance->ipcps) { + struct ipcp_entry * e = + list_entry(pos, struct ipcp_entry, next); + if (e->type == IPCP_SHIM_UDP) { + dif_name = e->dif_name; + break; + } + } + } + if (dif_name == NULL) return -1; diff --git a/src/irmd/registry.c b/src/irmd/registry.c index f688e1cc..32741460 100644 --- a/src/irmd/registry.c +++ b/src/irmd/registry.c @@ -63,7 +63,7 @@ struct reg_api * reg_api_create(pid_t api) i->state = REG_I_WAKE; pthread_mutex_init(&i->mutex, NULL); - pthread_cond_init(&i->wakeup, NULL); + pthread_cond_init(&i->cond_state, NULL); INIT_LIST_HEAD(&i->next); @@ -72,21 +72,18 @@ struct reg_api * reg_api_create(pid_t api) void reg_api_destroy(struct reg_api * i) { - bool wait = true; pthread_mutex_lock(&i->mutex); - i->state = REG_I_NULL; - pthread_cond_broadcast(&i->wakeup); + if (i->state != REG_I_SLEEP) + i->state = REG_I_WAKE; + else + i->state = REG_I_NULL; + + pthread_cond_broadcast(&i->cond_state); pthread_mutex_unlock(&i->mutex); - while (wait) { - pthread_mutex_lock(&i->mutex); - if (pthread_cond_destroy(&i->wakeup)) - pthread_cond_broadcast(&i->wakeup); - else - wait = false; - pthread_mutex_unlock(&i->mutex); - } + while (i->state != REG_I_WAKE) + ; pthread_mutex_destroy(&i->mutex); @@ -107,7 +104,10 @@ void reg_api_sleep(struct reg_api * i) (void *) &i->mutex); while (i->state == REG_I_SLEEP) - pthread_cond_wait(&i->wakeup, &i->mutex); + pthread_cond_wait(&i->cond_state, &i->mutex); + + i->state = REG_I_WAKE; + pthread_cond_signal(&i->cond_state); pthread_cleanup_pop(true); } @@ -123,7 +123,7 @@ void reg_api_wake(struct reg_api * i) i->state = REG_I_WAKE; - pthread_cond_signal(&i->wakeup); + pthread_cond_signal(&i->cond_state); pthread_mutex_unlock(&i->mutex); } @@ -674,27 +674,6 @@ char * registry_get_dif_for_dst(struct list_head * registry, return NULL; } else { LOG_DBGF("No local ap %s found.", dst_name); - list_for_each(pos, &re->difs) { - struct reg_dif * rd = - list_entry(pos, struct reg_dif, next); - if (rd->type == IPCP_NORMAL) - return rd->dif_name; - } - - list_for_each(pos, &re->difs) { - struct reg_dif * rd = - list_entry(pos, struct reg_dif, next); - if (rd->type == IPCP_SHIM_ETH_LLC) - return rd->dif_name; - } - - list_for_each(pos, &re->difs) { - struct reg_dif * rd = - list_entry(pos, struct reg_dif, next); - if (rd->type == IPCP_SHIM_UDP) - return rd->dif_name; - } - return NULL; } } diff --git a/src/irmd/registry.h b/src/irmd/registry.h index 04ce7cf8..8e9a7af1 100644 --- a/src/irmd/registry.h +++ b/src/irmd/registry.h @@ -59,7 +59,7 @@ struct reg_api { /* the api will block on this */ enum reg_i_state state; - pthread_cond_t wakeup; + pthread_cond_t cond_state; pthread_mutex_t mutex; }; |