From 18e440197cae6d537765a4de6a915f074dce4de5 Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Mon, 8 Aug 2016 21:15:57 +0200 Subject: irmd: Refactor and bugfixes Refactors the IRMd to extract reg_api and irm_flow structures to their own sources. Fixes some locking bugs. --- src/irmd/CMakeLists.txt | 2 + src/irmd/irm_flow.c | 81 ++++++++++++ src/irmd/irm_flow.h | 51 ++++++++ src/irmd/main.c | 320 ++++++++++++++++++++---------------------------- src/irmd/reg_api.c | 120 ++++++++++++++++++ src/irmd/reg_api.h | 55 +++++++++ src/irmd/registry.c | 113 +---------------- src/irmd/registry.h | 7 +- 8 files changed, 445 insertions(+), 304 deletions(-) create mode 100644 src/irmd/irm_flow.c create mode 100644 src/irmd/irm_flow.h create mode 100644 src/irmd/reg_api.c create mode 100644 src/irmd/reg_api.h (limited to 'src/irmd') 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 + * + * 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 + +#include "irm_flow.h" + +#include +#include + +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 + * + * 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 +#include + +#include +#include +#include + +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 #include @@ -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 + * Sander Vrijders + * + * 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 +#include + +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 + * Sander Vrijders + * + * 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 +#include +#include + +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 #include +#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); -- cgit v1.2.3