diff options
Diffstat (limited to 'src/irmd')
| -rw-r--r-- | src/irmd/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/irmd/irm_flow.c | 81 | ||||
| -rw-r--r-- | src/irmd/irm_flow.h | 51 | ||||
| -rw-r--r-- | src/irmd/main.c | 320 | ||||
| -rw-r--r-- | src/irmd/reg_api.c | 120 | ||||
| -rw-r--r-- | src/irmd/reg_api.h | 55 | ||||
| -rw-r--r-- | src/irmd/registry.c | 113 | ||||
| -rw-r--r-- | src/irmd/registry.h | 7 | 
8 files changed, 445 insertions, 304 deletions
| diff --git a/src/irmd/CMakeLists.txt b/src/irmd/CMakeLists.txt index bf810d96..89fbae08 100644 --- a/src/irmd/CMakeLists.txt +++ b/src/irmd/CMakeLists.txt @@ -6,7 +6,9 @@ include_directories(${CMAKE_BINARY_DIR}/include)  set(SOURCE_FILES          # Add source files here +        irm_flow.c          main.c +        reg_api.c          registry.c          utils.c  ) diff --git a/src/irmd/irm_flow.c b/src/irmd/irm_flow.c new file mode 100644 index 00000000..6531e4f6 --- /dev/null +++ b/src/irmd/irm_flow.c @@ -0,0 +1,81 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * The IPC Resource Manager - Flows + * + *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <ouroboros/config.h> + +#include "irm_flow.h" + +#include <stdlib.h> +#include <stdbool.h> + +struct irm_flow * irm_flow_create() +{ +        struct irm_flow * f = malloc(sizeof(*f)); +        if (f == NULL) +                return NULL; + +        f->n_api   = -1; +        f->n_1_api = -1; +        f->port_id = -1; +        f->state   = FLOW_NULL; + +        if (pthread_cond_init(&f->state_cond, NULL)) { +                free(f); +                return NULL; +        } + +        if (pthread_mutex_init(&f->state_lock, NULL)) { +                free(f); +                return NULL; +        } + +        f->t0.tv_sec  = 0; +        f->t0.tv_nsec = 0; + +        return f; +} + +void irm_flow_destroy(struct irm_flow * f) +{ +        pthread_mutex_lock(&f->state_lock); + +        if (f->state == FLOW_PENDING) +                f->state = FLOW_DESTROY; +        else +                f->state = FLOW_NULL; + +        pthread_cond_signal(&f->state_cond); +        pthread_mutex_unlock(&f->state_lock); + +        pthread_cleanup_push((void (*)(void *)) pthread_mutex_unlock, +                             (void *) &f->state_lock); + +        while (f->state != FLOW_NULL) +                pthread_cond_wait(&f->state_cond, &f->state_lock); + +        pthread_cleanup_pop(true); + +        pthread_cond_destroy(&f->state_cond); +        pthread_mutex_destroy(&f->state_lock); + +        free(f); +} diff --git a/src/irmd/irm_flow.h b/src/irmd/irm_flow.h new file mode 100644 index 00000000..b7e5a1be --- /dev/null +++ b/src/irmd/irm_flow.h @@ -0,0 +1,51 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * The IPC Resource Manager - Flows + * + *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef OUROBOROS_IRMD_IRM_FLOW_H +#define OUROBOROS_IRMD_IRM_FLOW_H + +#include <ouroboros/list.h> +#include <ouroboros/shared.h> + +#include <sys/types.h> +#include <pthread.h> +#include <time.h> + +struct irm_flow { +        struct list_head next; + +        int              port_id; + +        pid_t            n_api; +        pid_t            n_1_api; + +        struct timespec  t0; + +        enum flow_state  state; +        pthread_cond_t   state_cond; +        pthread_mutex_t  state_lock; +}; + +struct irm_flow * irm_flow_create(); +void              irm_flow_destroy(struct irm_flow * f); + +#endif /* OUROBOROS_IRMD_IRM_FLOW_H */ diff --git a/src/irmd/main.c b/src/irmd/main.c index 69ce765c..a79330ef 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -42,6 +42,7 @@  #include "utils.h"  #include "registry.h" +#include "irm_flow.h"  #include <sys/socket.h>  #include <sys/un.h> @@ -57,11 +58,11 @@  #define IRMD_CLEANUP_TIMER ((IRMD_FLOW_TIMEOUT / 20) * MILLION) /* ns */  struct ipcp_entry { -        struct list_head  next; -        char *            name; -        pid_t             api; -        enum ipcp_type    type; -        char *            dif_name; +        struct list_head next; +        char *           name; +        pid_t            api; +        enum ipcp_type   type; +        char *           dif_name;  };  enum irm_state { @@ -76,20 +77,6 @@ struct spawned_api {  };  /* keeps track of port_id's between N and N - 1 */ -struct irm_flow { -        struct list_head next; - -        int              port_id; - -        pid_t            n_api; -        pid_t            n_1_api; - -        struct timespec  t0; - -        enum flow_state  state; -        pthread_cond_t   state_cond; -        pthread_mutex_t  state_lock; -};  struct irm {          /* FIXME: list of ipcps could be merged into the registry */ @@ -118,59 +105,6 @@ struct irm {          pthread_t           shm_sanitize;  } * irmd = NULL; -static struct irm_flow * irm_flow_create() -{ -        struct irm_flow * e = malloc(sizeof(*e)); -        if (e == NULL) -                return NULL; - -        e->n_api   = -1; -        e->n_1_api = -1; -        e->port_id = -1; -        e->state   = FLOW_NULL; - -        if (pthread_cond_init(&e->state_cond, NULL)) { -                free(e); -                return NULL; -        } - -        if (pthread_mutex_init(&e->state_lock, NULL)) { -                free(e); -                return NULL; -        } - -        e->t0.tv_sec  = 0; -        e->t0.tv_nsec = 0; - -        return e; -} - -static void irm_flow_destroy(struct irm_flow * e) -{ -        pthread_mutex_lock(&e->state_lock); - -        if (e->state == FLOW_PENDING) -                e->state = FLOW_DESTROY; -        else -                e->state = FLOW_NULL; - -        pthread_cond_signal(&e->state_cond); -        pthread_mutex_unlock(&e->state_lock); - -        pthread_cleanup_push((void (*)(void *)) pthread_mutex_unlock, -                             (void *) &e->state_lock); - -        while (e->state != FLOW_NULL) -                pthread_cond_wait(&e->state_cond, &e->state_lock); - -        pthread_cleanup_pop(true); - -        pthread_cond_destroy(&e->state_cond); -        pthread_mutex_destroy(&e->state_lock); - -        free(e); -} -  static struct irm_flow * get_irm_flow(int port_id)  {          struct list_head * pos = NULL; @@ -294,8 +228,8 @@ static pid_t get_ipcp_by_dst_name(char * dst_name)  static pid_t create_ipcp(char *         name,                           enum ipcp_type ipcp_type)  { -        struct spawned_api * api; -        struct ipcp_entry * tmp = NULL; +        struct spawned_api * api = NULL; +        struct ipcp_entry *  tmp = NULL;          struct list_head * pos; @@ -738,9 +672,9 @@ static struct irm_flow * flow_accept(pid_t   api,                                       char *  srv_ap_name,                                       char ** dst_ae_name)  { -        struct irm_flow * pme = NULL; -        struct reg_entry *      rne = NULL; -        struct reg_api *        rgi = NULL; +        struct irm_flow *  f   = NULL; +        struct reg_entry * rne = NULL; +        struct reg_api *   rgi = NULL;          pthread_rwlock_rdlock(&irmd->state_lock); @@ -759,7 +693,7 @@ static struct irm_flow * flow_accept(pid_t   api,                  return NULL;          } -        if (!reg_entry_get_reg_api(rne, api)) { +        if ((rgi = reg_entry_get_reg_api(rne, api)) == NULL) {                  rgi = registry_add_api_name(&irmd->registry,                                              api,                                              rne->name); @@ -794,8 +728,8 @@ static struct irm_flow * flow_accept(pid_t   api,          pthread_rwlock_rdlock(&irmd->flows_lock); -        pme = get_irm_flow_n(api); -        if (pme == NULL) { +        f = get_irm_flow_n(api); +        if (f == NULL) {                  pthread_rwlock_unlock(&irmd->flows_lock);                  pthread_rwlock_unlock(&irmd->state_lock);                  LOG_ERR("Port_id was not created yet."); @@ -808,15 +742,15 @@ static struct irm_flow * flow_accept(pid_t   api,          pthread_rwlock_unlock(&irmd->flows_lock);          pthread_rwlock_unlock(&irmd->state_lock); -        return pme; +        return f;  }  static int flow_alloc_resp(pid_t n_api,                             int   port_id,                             int   response)  { -        struct irm_flow * pme = NULL; -        struct reg_entry * rne      = NULL; +        struct irm_flow * f    = NULL; +        struct reg_entry * rne = NULL;          int ret = -1;          pthread_rwlock_rdlock(&irmd->state_lock); @@ -835,15 +769,16 @@ static int flow_alloc_resp(pid_t n_api,                  return -1;          } +        pthread_mutex_lock(&rne->state_lock); +          if (rne->state != REG_NAME_FLOW_ARRIVED) { +                pthread_mutex_unlock(&rne->state_lock);                  pthread_rwlock_unlock(&irmd->reg_lock);                  pthread_rwlock_unlock(&irmd->state_lock);                  LOG_ERR("Process not listening for this name.");                  return -1;          } -        pthread_mutex_lock(&rne->state_lock); -          registry_del_api(&irmd->registry, n_api);          pthread_mutex_unlock(&rne->state_lock); @@ -853,20 +788,20 @@ static int flow_alloc_resp(pid_t n_api,          if (!response) {                  pthread_rwlock_wrlock(&irmd->flows_lock); -                pme = get_irm_flow(port_id); -                if (pme == NULL) { +                f = get_irm_flow(port_id); +                if (f == NULL) {                          pthread_rwlock_unlock(&irmd->flows_lock);                          pthread_rwlock_unlock(&irmd->state_lock);                          return -1;                  } -                pme->state = FLOW_ALLOCATED; -                pthread_cond_signal(&pme->state_cond); +                f->state = FLOW_ALLOCATED; +                pthread_cond_signal(&f->state_cond);                  pthread_rwlock_unlock(&irmd->flows_lock); -                ret = ipcp_flow_alloc_resp(pme->n_1_api, +                ret = ipcp_flow_alloc_resp(f->n_1_api,                                             port_id, -                                           pme->n_api, +                                           f->n_api,                                             response);          } @@ -880,7 +815,7 @@ static struct irm_flow * flow_alloc(pid_t  api,                                      char * src_ae_name,                                      struct qos_spec * qos)  { -        struct irm_flow * pme; +        struct irm_flow * f;          pid_t ipcp;          /* FIXME: Map qos_spec to qos_cube */ @@ -892,16 +827,16 @@ static struct irm_flow * flow_alloc(pid_t  api,                  return NULL;          } -        pme = irm_flow_create(); -        if (pme == NULL) { +        f = irm_flow_create(); +        if (f == NULL) {                  pthread_rwlock_unlock(&irmd->state_lock);                  LOG_ERR("Failed to create irm_flow.");                  return NULL;          } -        pme->n_api = api; -        pme->state = FLOW_PENDING; -        if (clock_gettime(CLOCK_MONOTONIC, &pme->t0) < 0) +        f->n_api = api; +        f->state = FLOW_PENDING; +        if (clock_gettime(CLOCK_MONOTONIC, &f->t0) < 0)                  LOG_WARN("Failed to set timestamp.");          pthread_rwlock_rdlock(&irmd->reg_lock); @@ -917,44 +852,44 @@ static struct irm_flow * flow_alloc(pid_t  api,          pthread_rwlock_unlock(&irmd->reg_lock);          pthread_rwlock_wrlock(&irmd->flows_lock); -        pme->port_id = bmp_allocate(irmd->port_ids); -        pme->n_1_api = ipcp; +        f->port_id = bmp_allocate(irmd->port_ids); +        f->n_1_api = ipcp; -        list_add(&pme->next, &irmd->irm_flows); +        list_add(&f->next, &irmd->irm_flows);          pthread_rwlock_unlock(&irmd->flows_lock);          pthread_rwlock_unlock(&irmd->state_lock);          if (ipcp_flow_alloc(ipcp, -                            pme->port_id, -                            pme->n_api, +                            f->port_id, +                            f->n_api,                              dst_name,                              src_ae_name,                              QOS_CUBE_BE) < 0) {                  pthread_rwlock_rdlock(&irmd->state_lock);                  pthread_rwlock_wrlock(&irmd->flows_lock); -                list_del(&pme->next); -                bmp_release(irmd->port_ids, pme->port_id); +                list_del(&f->next); +                bmp_release(irmd->port_ids, f->port_id);                  pthread_rwlock_unlock(&irmd->flows_lock);                  pthread_rwlock_unlock(&irmd->state_lock); -                free(pme); +                free(f);                  return NULL;          } -        return pme; +        return f;  }  static void cleanup_alloc_res(void * o)  { -        struct irm_flow * e = (struct irm_flow *) o; -        if (e->state == FLOW_PENDING) -                e->state = FLOW_NULL; -        pthread_mutex_unlock(&e->state_lock); +        struct irm_flow * f = (struct irm_flow *) o; +        if (f->state == FLOW_PENDING) +                f->state = FLOW_NULL; +        pthread_mutex_unlock(&f->state_lock);  }  static int flow_alloc_res(int port_id)  { -        struct irm_flow * e; +        struct irm_flow * f;          pthread_rwlock_rdlock(&irmd->state_lock); @@ -964,22 +899,22 @@ static int flow_alloc_res(int port_id)          }          pthread_rwlock_rdlock(&irmd->flows_lock); -        e = get_irm_flow(port_id); -        if (e == NULL) { +        f = get_irm_flow(port_id); +        if (f == NULL) {                  LOG_ERR("Could not find port %d.", port_id);                  pthread_rwlock_unlock(&irmd->flows_lock);                  pthread_rwlock_unlock(&irmd->state_lock);                  return -1;          } -        if (e->state == FLOW_NULL) { +        if (f->state == FLOW_NULL) {                  LOG_INFO("Port %d is deprecated.", port_id);                  pthread_rwlock_unlock(&irmd->flows_lock);                  pthread_rwlock_unlock(&irmd->state_lock);                  return -1;          } -        if (e->state == FLOW_ALLOCATED) { +        if (f->state == FLOW_ALLOCATED) {                  pthread_rwlock_unlock(&irmd->flows_lock);                  pthread_rwlock_unlock(&irmd->state_lock);                  return 0; @@ -988,28 +923,28 @@ static int flow_alloc_res(int port_id)          pthread_rwlock_unlock(&irmd->flows_lock);          pthread_rwlock_unlock(&irmd->state_lock); -        pthread_mutex_lock(&e->state_lock); -        pthread_cleanup_push(cleanup_alloc_res, (void *) e); +        pthread_mutex_lock(&f->state_lock); +        pthread_cleanup_push(cleanup_alloc_res, (void *) f); -        while (e->state == FLOW_PENDING) -                pthread_cond_wait(&e->state_cond, &e->state_lock); +        while (f->state == FLOW_PENDING) +                pthread_cond_wait(&f->state_cond, &f->state_lock);          pthread_cleanup_pop(true);          pthread_rwlock_rdlock(&irmd->state_lock);          pthread_rwlock_wrlock(&irmd->flows_lock); -        pthread_mutex_lock(&e->state_lock); +        pthread_mutex_lock(&f->state_lock); -        if (e->state == FLOW_ALLOCATED) { -                pthread_mutex_unlock(&e->state_lock); +        if (f->state == FLOW_ALLOCATED) { +                pthread_mutex_unlock(&f->state_lock);                  pthread_rwlock_unlock(&irmd->flows_lock);                  pthread_rwlock_unlock(&irmd->state_lock);                  return 0;          } -        e->state = FLOW_NULL; -        pthread_cond_signal(&e->state_cond); -        pthread_mutex_unlock(&e->state_lock); +        f->state = FLOW_NULL; +        pthread_cond_signal(&f->state_cond); +        pthread_mutex_unlock(&f->state_lock);          pthread_rwlock_unlock(&irmd->flows_lock);          pthread_rwlock_unlock(&irmd->state_lock); @@ -1021,22 +956,22 @@ static int flow_dealloc(int port_id)          pid_t n_1_api;          int   ret = 0; -        struct irm_flow * e = NULL; +        struct irm_flow * f = NULL;          pthread_rwlock_rdlock(&irmd->state_lock);          pthread_rwlock_wrlock(&irmd->flows_lock);          bmp_release(irmd->port_ids, port_id); -        e = get_irm_flow(port_id); -        if (e == NULL) { +        f = get_irm_flow(port_id); +        if (f == NULL) {                  pthread_rwlock_unlock(&irmd->flows_lock);                  pthread_rwlock_unlock(&irmd->state_lock);                  return 0;          } -        n_1_api = e->n_1_api; +        n_1_api = f->n_1_api; -        list_del(&e->next); +        list_del(&f->next);          pthread_rwlock_unlock(&irmd->flows_lock); @@ -1044,7 +979,7 @@ static int flow_dealloc(int port_id)          pthread_rwlock_unlock(&irmd->state_lock); -        irm_flow_destroy(e); +        irm_flow_destroy(f);          return ret;  } @@ -1085,22 +1020,23 @@ static struct irm_flow * flow_req_arr(pid_t  api,                                        char * dst_name,                                        char * ae_name)  { -        struct reg_entry *      rne = NULL; -        struct irm_flow * pme = NULL; +        struct reg_entry * rne = NULL; +        struct irm_flow *  f   = NULL; +        struct reg_api *   rgi = NULL;          enum reg_name_state state;          struct spawned_api * c_api; -        pme = irm_flow_create(); -        if (pme == NULL) { +        f = irm_flow_create(); +        if (f == NULL) {                  LOG_ERR("Failed to create irm_flow.");                  return NULL;          } -        pme->state   = FLOW_PENDING; -        pme->n_1_api = api; -        if (clock_gettime(CLOCK_MONOTONIC, &pme->t0) < 0) +        f->state   = FLOW_PENDING; +        f->n_1_api = api; +        if (clock_gettime(CLOCK_MONOTONIC, &f->t0) < 0)                  LOG_WARN("Failed to set timestamp.");          pthread_rwlock_rdlock(&irmd->state_lock); @@ -1111,7 +1047,7 @@ static struct irm_flow * flow_req_arr(pid_t  api,                  pthread_rwlock_unlock(&irmd->reg_lock);                  pthread_rwlock_unlock(&irmd->state_lock);                  LOG_ERR("Unknown name: %s.", dst_name); -                free(pme); +                free(f);                  return NULL;          } @@ -1124,14 +1060,14 @@ static struct irm_flow * flow_req_arr(pid_t  api,                  pthread_rwlock_unlock(&irmd->reg_lock);                  pthread_rwlock_unlock(&irmd->state_lock);                  LOG_ERR("No AP's for %s.", dst_name); -                free(pme); +                free(f);                  return NULL;          case REG_NAME_AUTO_ACCEPT:                  c_api = malloc(sizeof(*c_api));                  if (c_api == NULL) {                          pthread_rwlock_unlock(&irmd->reg_lock);                          pthread_rwlock_unlock(&irmd->state_lock); -                        free(pme); +                        free(f);                          return NULL;                  } @@ -1146,7 +1082,7 @@ static struct irm_flow * flow_req_arr(pid_t  api,                          pthread_mutex_unlock(&rne->state_lock);                          pthread_rwlock_unlock(&irmd->reg_lock);                          pthread_rwlock_unlock(&irmd->state_lock); -                        free(pme); +                        free(f);                          free(c_api);                          return NULL;                  } @@ -1154,6 +1090,7 @@ static struct irm_flow * flow_req_arr(pid_t  api,                  list_add(&c_api->next, &irmd->spawned_apis);                  pthread_rwlock_unlock(&irmd->reg_lock); +                pthread_rwlock_unlock(&irmd->state_lock);                  pthread_mutex_lock(&rne->state_lock);                  pthread_cleanup_push((void (*)(void *)) pthread_mutex_unlock, @@ -1164,18 +1101,20 @@ static struct irm_flow * flow_req_arr(pid_t  api,                  pthread_cleanup_pop(true); +                pthread_rwlock_rdlock(&irmd->state_lock);                  pthread_rwlock_rdlock(&irmd->reg_lock);                  pthread_mutex_lock(&rne->state_lock);                  if (rne->state == REG_NAME_DESTROY) {                          rne->state = REG_NAME_NULL;                          pthread_mutex_unlock(&rne->state_lock);                          pthread_rwlock_unlock(&irmd->reg_lock); +                        pthread_rwlock_unlock(&irmd->state_lock);                          return NULL;                  }                  pthread_mutex_unlock(&rne->state_lock);          case REG_NAME_FLOW_ACCEPT: -                pme->n_api = reg_entry_resolve_api(rne); -                if (pme->n_api == -1) { +                f->n_api = reg_entry_resolve_api(rne); +                if (f->n_api == -1) {                          pthread_rwlock_unlock(&irmd->reg_lock);                          pthread_rwlock_unlock(&irmd->state_lock);                          LOG_ERR("Invalid api returned."); @@ -1187,70 +1126,73 @@ static struct irm_flow * flow_req_arr(pid_t  api,                  pthread_rwlock_unlock(&irmd->reg_lock);                  pthread_rwlock_unlock(&irmd->state_lock);                  LOG_ERR("IRMd in wrong state."); -                free(pme); +                free(f);                  return NULL;          }          pthread_rwlock_unlock(&irmd->reg_lock);          pthread_rwlock_wrlock(&irmd->flows_lock); -        pme->port_id = bmp_allocate(irmd->port_ids); +        f->port_id = bmp_allocate(irmd->port_ids); -        list_add(&pme->next, &irmd->irm_flows); +        list_add(&f->next, &irmd->irm_flows);          pthread_rwlock_unlock(&irmd->flows_lock); +        pthread_rwlock_rdlock(&irmd->reg_lock);          pthread_mutex_lock(&rne->state_lock);          rne->req_ae_name = ae_name;          rne->state = REG_NAME_FLOW_ARRIVED; -        reg_api_wake(reg_entry_get_reg_api(rne, pme->n_api)); +        rgi = reg_entry_get_reg_api(rne, f->n_api);          pthread_mutex_unlock(&rne->state_lock); - +        pthread_rwlock_unlock(&irmd->reg_lock);          pthread_rwlock_unlock(&irmd->state_lock); +        reg_api_wake(rgi); + +        pthread_mutex_lock(&rne->state_lock);          pthread_cleanup_push((void (*)(void *)) pthread_mutex_unlock,                               (void *) &rne->state_lock); -        while (rne->state == REG_NAME_FLOW_ARRIVED && -               irmd->state == IRMD_RUNNING) +        while (rne->state == REG_NAME_FLOW_ARRIVED)                  pthread_cond_wait(&rne->state_cond, &rne->state_lock);          pthread_cleanup_pop(true); -        return pme; +        return f;  }  static int flow_alloc_reply(int port_id,                              int response)  { -        struct irm_flow * e; +        struct irm_flow * f;          pthread_rwlock_rdlock(&irmd->state_lock);          pthread_rwlock_rdlock(&irmd->flows_lock); -        e = get_irm_flow(port_id); -        if (e == NULL) { +        f = get_irm_flow(port_id); +        if (f == NULL) {                  pthread_rwlock_unlock(&irmd->flows_lock);                  pthread_rwlock_unlock(&irmd->state_lock);                  return -1;          } -        pthread_mutex_lock(&e->state_lock); +        pthread_mutex_lock(&f->state_lock);          if (!response) -                e->state = FLOW_ALLOCATED; +                f->state = FLOW_ALLOCATED;          else -                e->state = FLOW_NULL; +                f->state = FLOW_NULL; -        if (pthread_cond_signal(&e->state_cond)) +        if (pthread_cond_signal(&f->state_cond))                  LOG_ERR("Failed to send signal."); -        pthread_mutex_unlock(&e->state_lock); +        pthread_mutex_unlock(&f->state_lock);          pthread_rwlock_unlock(&irmd->flows_lock);          pthread_rwlock_unlock(&irmd->state_lock); @@ -1260,24 +1202,24 @@ static int flow_alloc_reply(int port_id,  static int flow_dealloc_ipcp(int port_id)  { -        struct irm_flow * e = NULL; +        struct irm_flow * f = NULL;          pthread_rwlock_rdlock(&irmd->state_lock);          pthread_rwlock_wrlock(&irmd->flows_lock); -        e = get_irm_flow(port_id); -        if (e == NULL) { +        f = get_irm_flow(port_id); +        if (f == NULL) {                  pthread_rwlock_unlock(&irmd->flows_lock);                  pthread_rwlock_unlock(&irmd->state_lock);                  return 0;          } -        list_del(&e->next); +        list_del(&f->next);          pthread_rwlock_unlock(&irmd->flows_lock);          pthread_rwlock_unlock(&irmd->state_lock); -        irm_flow_destroy(e); +        irm_flow_destroy(f);          return 0;  } @@ -1324,9 +1266,9 @@ static void irm_destroy()          pthread_rwlock_wrlock(&irmd->flows_lock);          list_for_each_safe(h, t, &irmd->irm_flows) { -                struct irm_flow * e = list_entry(h, struct irm_flow, next); -                list_del(&e->next); -                irm_flow_destroy(e); +                struct irm_flow * f = list_entry(h, struct irm_flow, next); +                list_del(&f->next); +                irm_flow_destroy(f);          }          if (irmd->port_ids != NULL) @@ -1405,46 +1347,46 @@ void * irm_flow_cleaner()                  pthread_rwlock_wrlock(&irmd->flows_lock);                  list_for_each_safe(pos, n, &(irmd->irm_flows)) { -                        struct irm_flow * e = +                        struct irm_flow * f =                                  list_entry(pos, struct irm_flow, next); -                        pthread_mutex_lock(&e->state_lock); +                        pthread_mutex_lock(&f->state_lock); -                        if (e->state == FLOW_PENDING && -                            ts_diff_ms(&e->t0, &now) > IRMD_FLOW_TIMEOUT) { +                        if (f->state == FLOW_PENDING && +                            ts_diff_ms(&f->t0, &now) > IRMD_FLOW_TIMEOUT) {                                  LOG_INFO("Pending port_id %d timed out.", -                                         e->port_id); -                                e->state = FLOW_NULL; -                                pthread_cond_signal(&e->state_cond); -                                pthread_mutex_unlock(&e->state_lock); +                                         f->port_id); +                                f->state = FLOW_NULL; +                                pthread_cond_signal(&f->state_cond); +                                pthread_mutex_unlock(&f->state_lock);                                  continue;                          } -                        pthread_mutex_unlock(&e->state_lock); +                        pthread_mutex_unlock(&f->state_lock); -                        if (kill(e->n_api, 0) < 0) { +                        if (kill(f->n_api, 0) < 0) {                                  struct shm_ap_rbuff * n_rb = -                                        shm_ap_rbuff_open(e->n_api); -                                bmp_release(irmd->port_ids, e->port_id); +                                        shm_ap_rbuff_open(f->n_api); +                                bmp_release(irmd->port_ids, f->port_id); -                                list_del(&e->next); +                                list_del(&f->next);                                  LOG_INFO("Process %d gone, %d deallocated.", -                                         e->n_api, e->port_id); -                                ipcp_flow_dealloc(e->n_1_api, e->port_id); +                                         f->n_api, f->port_id); +                                ipcp_flow_dealloc(f->n_1_api, f->port_id);                                  if (n_rb != NULL)                                          shm_ap_rbuff_destroy(n_rb); -                                irm_flow_destroy(e); +                                irm_flow_destroy(f);                                  continue;                          } -                        if (kill(e->n_1_api, 0) < 0) { +                        if (kill(f->n_1_api, 0) < 0) {                                  struct shm_ap_rbuff * n_1_rb = -                                        shm_ap_rbuff_open(e->n_1_api); -                                list_del(&e->next); +                                        shm_ap_rbuff_open(f->n_1_api); +                                list_del(&f->next);                                  LOG_ERR("IPCP %d gone, flow %d removed.", -                                        e->n_1_api, e->port_id); +                                        f->n_1_api, f->port_id);                                  if (n_1_rb != NULL)                                          shm_ap_rbuff_destroy(n_1_rb); -                                irm_flow_destroy(e); +                                irm_flow_destroy(f);                          }                  } diff --git a/src/irmd/reg_api.c b/src/irmd/reg_api.c new file mode 100644 index 00000000..e2da1244 --- /dev/null +++ b/src/irmd/reg_api.c @@ -0,0 +1,120 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * The IPC Resource Manager - Registered Application Instances + * + *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> + *    Sander Vrijders   <sander.vrijders@intec.ugent.be> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "reg_api.h" + +#include <stdlib.h> +#include <stdbool.h> + +struct reg_api * reg_api_create(pid_t api) +{ +        struct reg_api * i; +        i = malloc(sizeof(*i)); +        if (i == NULL) +                return NULL; + +        i->api   = api; +        i->state = REG_I_INIT; + +        pthread_mutex_init(&i->state_lock, NULL); +        pthread_cond_init(&i->state_cond, NULL); + +        INIT_LIST_HEAD(&i->next); + +        return i; +} + +void reg_api_destroy(struct reg_api * i) +{ +        if (i == NULL) +                return; + +        pthread_mutex_lock(&i->state_lock); + +        if (i->state != REG_I_NULL) +                i->state = REG_I_DESTROY; + +        pthread_cond_signal(&i->state_cond); + +        pthread_mutex_unlock(&i->state_lock); + +        pthread_cleanup_push((void(*)(void *)) pthread_mutex_unlock, +                             (void *) &i->state_lock); + +        while (i->state != REG_I_NULL) +                pthread_cond_wait(&i->state_cond, &i->state_lock); + +        pthread_cleanup_pop(true); + +        pthread_cond_destroy(&i->state_cond); +        pthread_mutex_destroy(&i->state_lock); + +        free(i); +} + +static void cleanup_sleeper(void * o) { +        struct reg_api * i = (struct reg_api *) o; +        i->state = REG_I_NULL; +        pthread_cond_signal(&i->state_cond); +        pthread_mutex_unlock(&i->state_lock); +} + +void reg_api_sleep(struct reg_api * i) +{ +        if (i == NULL) +                return; + +        pthread_mutex_lock(&i->state_lock); +        if (i->state != REG_I_INIT) { +                pthread_mutex_unlock(&i->state_lock); +                return; +        } + +        i->state = REG_I_SLEEP; + +        pthread_cleanup_push(cleanup_sleeper, (void *) i); + +        while (i->state == REG_I_SLEEP) +                pthread_cond_wait(&i->state_cond, &i->state_lock); + +        pthread_cleanup_pop(true); +} + +void reg_api_wake(struct reg_api * i) +{ +        pthread_mutex_lock(&i->state_lock); + +        if (i->state == REG_I_NULL) { +                pthread_mutex_unlock(&i->state_lock); +                return; +        } + +        i->state = REG_I_WAKE; + +        pthread_cond_broadcast(&i->state_cond); + +        while (i->state == REG_I_WAKE) +                pthread_cond_wait(&i->state_cond, &i->state_lock); + +        pthread_mutex_unlock(&i->state_lock); +} diff --git a/src/irmd/reg_api.h b/src/irmd/reg_api.h new file mode 100644 index 00000000..73e1141b --- /dev/null +++ b/src/irmd/reg_api.h @@ -0,0 +1,55 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * The IPC Resource Manager - Registered Application Instances + * + *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> + *    Sander Vrijders   <sander.vrijders@intec.ugent.be> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#ifndef OUROBOROS_IRMD_REG_API_H +#define OUROBOROS_IRMD_REG_API_H + +#include <ouroboros/list.h> +#include <sys/types.h> +#include <pthread.h> + +enum api_state { +        REG_I_NULL = 0, +        REG_I_INIT, +        REG_I_SLEEP, +        REG_I_WAKE, +        REG_I_DESTROY +}; + +struct reg_api { +        struct list_head next; +        pid_t            api; + +        /* the api will block on this */ +        enum api_state   state; +        pthread_cond_t   state_cond; +        pthread_mutex_t  state_lock; +}; + +struct reg_api * reg_api_create(pid_t pid); +void             reg_api_destroy(struct reg_api * i); +void             reg_api_sleep(struct reg_api * i); +void             reg_api_wake(struct reg_api * i); + +#endif /* OUROBOROS_IRMD_REG_API_H */ diff --git a/src/irmd/registry.c b/src/irmd/registry.c index 7745efaa..ec1c3987 100644 --- a/src/irmd/registry.c +++ b/src/irmd/registry.c @@ -53,117 +53,9 @@ struct reg_dif {          enum ipcp_type   type;  }; -enum api_state { -        REG_I_NULL = 0, -        REG_I_INIT, -        REG_I_SLEEP, -        REG_I_WAKE, -        REG_I_DESTROY -}; - -struct reg_api { -        struct list_head next; -        pid_t            api; - -        /* the api will block on this */ -        enum api_state   state; -        pthread_cond_t   state_cond; -        pthread_mutex_t  state_lock; -}; - -static struct reg_api * reg_api_create(pid_t api) -{ -        struct reg_api * i; -        i = malloc(sizeof(*i)); -        if (i == NULL) -                return NULL; - -        i->api   = api; -        i->state = REG_I_INIT; - -        pthread_mutex_init(&i->state_lock, NULL); -        pthread_cond_init(&i->state_cond, NULL); - -        INIT_LIST_HEAD(&i->next); - -        return i; -} - -static void reg_api_destroy(struct reg_api * i) -{ -        pthread_mutex_lock(&i->state_lock); - -        if (i->state != REG_I_NULL) -                i->state = REG_I_DESTROY; - -        pthread_cond_signal(&i->state_cond); - -        pthread_mutex_unlock(&i->state_lock); - -        pthread_cleanup_push((void(*)(void *)) pthread_mutex_unlock, -                             (void *) &i->state_lock); - -        while (i->state != REG_I_NULL) -                pthread_cond_wait(&i->state_cond, &i->state_lock); - -        pthread_cleanup_pop(true); - -        pthread_cond_destroy(&i->state_cond); -        pthread_mutex_destroy(&i->state_lock); - -        free(i); -} - -static void cleanup_sleeper(void * o) { -        struct reg_api * i = (struct reg_api *) o; -        i->state = REG_I_NULL; -        pthread_cond_signal(&i->state_cond); -        pthread_mutex_unlock(&i->state_lock); -} - -void reg_api_sleep(struct reg_api * i) -{ -        if (i == NULL) -                return; - -        pthread_mutex_lock(&i->state_lock); -        if (i->state != REG_I_INIT) { -                pthread_mutex_unlock(&i->state_lock); -                return; -        } - -        i->state = REG_I_SLEEP; - -        pthread_cleanup_push(cleanup_sleeper, (void *) i); - -        while (i->state == REG_I_SLEEP) -                pthread_cond_wait(&i->state_cond, &i->state_lock); - -        pthread_cleanup_pop(true); -} - -void reg_api_wake(struct reg_api * i) -{ -        pthread_mutex_lock(&i->state_lock); - -        if (i->state == REG_I_NULL) { -                pthread_mutex_unlock(&i->state_lock); -                return; -        } - -        i->state = REG_I_WAKE; - -        pthread_cond_broadcast(&i->state_cond); - -        while (i->state == REG_I_WAKE) -                pthread_cond_wait(&i->state_cond, &i->state_lock); - -        pthread_mutex_unlock(&i->state_lock); -} -  static struct reg_binding * reg_binding_create(char *   apn, -                                        uint32_t flags, -                                        char **  argv) +                                               uint32_t flags, +                                               char **  argv)  {          struct reg_binding * b = malloc(sizeof(*b));          if (b == NULL) @@ -248,6 +140,7 @@ static void reg_entry_destroy(struct reg_entry * e)          pthread_cond_broadcast(&e->state_cond);          pthread_mutex_unlock(&e->state_lock); +        pthread_cond_destroy(&e->state_cond);          pthread_mutex_destroy(&e->state_lock);          if (e->name != NULL) diff --git a/src/irmd/registry.h b/src/irmd/registry.h index fb0dceb7..19e27a21 100644 --- a/src/irmd/registry.h +++ b/src/irmd/registry.h @@ -33,6 +33,8 @@  #include <string.h>  #include <sys/types.h> +#include "reg_api.h" +  #define registry_has_name(r, name) \          (registry_get_entry_by_name(r, name) != NULL)  #define registry_name_has_api(r, name) \ @@ -48,8 +50,6 @@ enum reg_name_state {          REG_NAME_DESTROY  }; -struct reg_api; -  /* an entry in the registry */  struct reg_entry {          struct list_head    next; @@ -71,9 +71,6 @@ struct reg_entry {          pthread_mutex_t     state_lock;  }; -void                  reg_api_sleep(struct reg_api * i); -void                  reg_api_wake(struct reg_api * i); -  struct reg_binding *  reg_entry_get_binding(struct reg_entry * e,                                              char *             apn);  char **               reg_entry_get_auto_info(struct reg_entry * e); | 
