summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordimitri staessens <dimitri.staessens@intec.ugent.be>2016-07-15 15:49:23 +0200
committerdimitri staessens <dimitri.staessens@intec.ugent.be>2016-07-15 15:49:23 +0200
commite14d0da88d4f3fcd0c19c231b59d31189c4d71ad (patch)
tree936e0f4857a48a4be17087c2d32b754b09433747
parent71956f22abec7bb15f6bfc52b4168ff85499eea1 (diff)
downloadouroboros-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.c30
-rw-r--r--src/irmd/registry.c49
-rw-r--r--src/irmd/registry.h2
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;
};