summaryrefslogtreecommitdiff
path: root/src/irmd
diff options
context:
space:
mode:
authorSander Vrijders <sander.vrijders@intec.ugent.be>2016-08-10 12:27:41 +0200
committerSander Vrijders <sander.vrijders@intec.ugent.be>2016-08-10 12:54:38 +0200
commit155fbfb32b9a69705a06a5771bd146c1bed22821 (patch)
tree0a9654e87dd7d5818c3ecedd850a6b6f5641e369 /src/irmd
parent3eb6acfd135cdfb82d19a4f445776ea2f13fd4e1 (diff)
downloadouroboros-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.c50
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);