diff options
author | Sander Vrijders <sander.vrijders@intec.ugent.be> | 2016-08-10 12:27:41 +0200 |
---|---|---|
committer | Sander Vrijders <sander.vrijders@intec.ugent.be> | 2016-08-10 12:54:38 +0200 |
commit | 155fbfb32b9a69705a06a5771bd146c1bed22821 (patch) | |
tree | 0a9654e87dd7d5818c3ecedd850a6b6f5641e369 /src/irmd | |
parent | 3eb6acfd135cdfb82d19a4f445776ea2f13fd4e1 (diff) | |
download | ouroboros-155fbfb32b9a69705a06a5771bd146c1bed22821.tar.gz ouroboros-155fbfb32b9a69705a06a5771bd146c1bed22821.zip |
ipcp, irmd, lib: Notify IRMd upon IPCP initialization
This will notify the IRMd when the IPCP is initialized and ready to
receive messages. Previously a bootstrap could fail since the IPCP was
not listening to the socket yet.
Diffstat (limited to 'src/irmd')
-rw-r--r-- | src/irmd/main.c | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/src/irmd/main.c b/src/irmd/main.c index 8503fcfa..27f57077 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -63,6 +63,9 @@ struct ipcp_entry { pid_t api; enum ipcp_type type; char * dif_name; + pthread_cond_t init_cond; + pthread_mutex_t init_lock; + bool init; }; enum irm_state { @@ -244,8 +247,11 @@ static pid_t create_ipcp(char * name, return -1; } + pthread_rwlock_wrlock(&irmd->reg_lock); + api->api = ipcp_create(ipcp_type); if (api->api == -1) { + pthread_rwlock_unlock(&irmd->reg_lock); pthread_rwlock_unlock(&irmd->state_lock); LOG_ERR("Failed to create IPCP."); return -1; @@ -253,6 +259,7 @@ static pid_t create_ipcp(char * name, tmp = ipcp_entry_create(); if (tmp == NULL) { + pthread_rwlock_unlock(&irmd->reg_lock); pthread_rwlock_unlock(&irmd->state_lock); return -1; } @@ -263,14 +270,17 @@ static pid_t create_ipcp(char * name, tmp->name = strdup(name); if (tmp->name == NULL) { ipcp_entry_destroy(tmp); + pthread_rwlock_unlock(&irmd->reg_lock); pthread_rwlock_unlock(&irmd->state_lock); return -1; } + pthread_cond_init(&tmp->init_cond, NULL); + pthread_mutex_init(&tmp->init_lock, NULL); + tmp->dif_name = NULL; tmp->type = ipcp_type; - - pthread_rwlock_wrlock(&irmd->reg_lock); + tmp->init = false; list_for_each(pos, &irmd->ipcps) { struct ipcp_entry * e = @@ -283,14 +293,46 @@ static pid_t create_ipcp(char * name, list_add(&api->next, &irmd->spawned_apis); + pthread_mutex_lock(&tmp->init_lock); + pthread_rwlock_unlock(&irmd->reg_lock); pthread_rwlock_unlock(&irmd->state_lock); + while (tmp->init == false) + pthread_cond_wait(&tmp->init_cond, &tmp->init_lock); + + pthread_mutex_unlock(&tmp->init_lock); + LOG_INFO("Created IPCP %d.", api->api); return api->api; } +static int create_ipcp_r(pid_t api) +{ + struct list_head * pos = NULL; + + pthread_rwlock_rdlock(&irmd->state_lock); + pthread_rwlock_rdlock(&irmd->reg_lock); + + list_for_each(pos, &irmd->ipcps) { + struct ipcp_entry * e = + list_entry(pos, struct ipcp_entry, next); + + if (e->api == api) { + pthread_mutex_lock(&e->init_lock); + e->init = true; + pthread_cond_broadcast(&e->init_cond); + pthread_mutex_unlock(&e->init_lock); + } + } + + pthread_rwlock_unlock(&irmd->reg_lock); + pthread_rwlock_unlock(&irmd->state_lock); + + return 0; +} + static void clear_spawned_api(pid_t api) { struct list_head * pos = NULL; @@ -1480,6 +1522,10 @@ void * mainloop() ret_msg.result = create_ipcp(msg->dst_name, msg->ipcp_type); break; + case IRM_MSG_CODE__IPCP_CREATE_R: + ret_msg.has_result = true; + ret_msg.result = create_ipcp_r(msg->api); + break; case IRM_MSG_CODE__IRM_DESTROY_IPCP: ret_msg.has_result = true; ret_msg.result = destroy_ipcp(msg->api); |