diff options
| author | dimitri staessens <dimitri.staessens@intec.ugent.be> | 2016-08-10 13:03:33 +0200 | 
|---|---|---|
| committer | dimitri staessens <dimitri.staessens@intec.ugent.be> | 2016-08-10 13:03:33 +0200 | 
| commit | 9740c4bf2966d57d6f7e0d034a862211cb3814c4 (patch) | |
| tree | 9b33b5d1888cd4fb338b57b7b1aa90349668eb8b /src/irmd | |
| parent | aca897331ff55c80d926b0bdb90f1c8962bf7a6e (diff) | |
| parent | e5cb8042c9f0c6374c4f14bf7ff3f4fe3cdcd155 (diff) | |
| download | ouroboros-9740c4bf2966d57d6f7e0d034a862211cb3814c4.tar.gz ouroboros-9740c4bf2966d57d6f7e0d034a862211cb3814c4.zip | |
Merge branch 'be' of bitbucket.org:ouroboros-rina/ouroboros into be-bugfixing
Diffstat (limited to 'src/irmd')
| -rw-r--r-- | src/irmd/main.c | 63 | 
1 files changed, 61 insertions, 2 deletions
| diff --git a/src/irmd/main.c b/src/irmd/main.c index c2058ed5..e36fb98e 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 { @@ -243,8 +246,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; @@ -252,6 +258,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;          } @@ -262,14 +269,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 = @@ -282,14 +292,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; @@ -1320,6 +1362,8 @@ void * irm_flow_cleaner()          struct timespec now;          struct list_head * pos = NULL;          struct list_head * n   = NULL; +        struct list_head * h   = NULL; +        struct list_head * t   = NULL;          struct timespec timeout = {IRMD_CLEANUP_TIMER / BILLION,                                     IRMD_CLEANUP_TIMER % BILLION}; @@ -1398,6 +1442,17 @@ void * irm_flow_cleaner()                                  LOG_INFO("Spawned process %d terminated "                                           "with exit status %d.",                                           api->api, status); + +                                list_for_each_safe(h, t, &irmd->ipcps) { +                                        struct ipcp_entry * e = +                                                list_entry(h, struct ipcp_entry, +                                                           next); +                                        if (e->api == api->api) { +                                                list_del(&e->next); +                                                ipcp_entry_destroy(e); +                                        } +                                } +                                  list_del(&api->next);                                  free(api);                          } @@ -1455,6 +1510,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); | 
