diff options
author | dimitri staessens <[email protected]> | 2017-03-30 20:33:22 +0200 |
---|---|---|
committer | dimitri staessens <[email protected]> | 2017-03-31 11:51:33 +0200 |
commit | 7ba0fd0ce19244745c8d2512ce8a003783d914a7 (patch) | |
tree | e33ed7dae832ef96cd1997ec038764fac5d95d4c /src/irmd | |
parent | bce97d70ce43290f8351f34c763b30bfd73e6b99 (diff) | |
download | ouroboros-7ba0fd0ce19244745c8d2512ce8a003783d914a7.tar.gz ouroboros-7ba0fd0ce19244745c8d2512ce8a003783d914a7.zip |
lib: Revise flow allocation API
The flow_alloc_res and flow_alloc_resp calls have been removed. The
flow_alloc and flow_accept calls are now both blocking and take an
additional timeout argument.
Diffstat (limited to 'src/irmd')
-rw-r--r-- | src/irmd/ipcp.c | 7 | ||||
-rw-r--r-- | src/irmd/irm_flow.c | 12 | ||||
-rw-r--r-- | src/irmd/main.c | 203 |
3 files changed, 68 insertions, 154 deletions
diff --git a/src/irmd/ipcp.c b/src/irmd/ipcp.c index 06b66d3b..a8263580 100644 --- a/src/irmd/ipcp.c +++ b/src/irmd/ipcp.c @@ -176,18 +176,11 @@ pid_t ipcp_create(char * name, int ipcp_destroy(pid_t api) { - int status; - if (kill(api, SIGTERM)) { log_err("Failed to destroy IPCP"); return -1; } - if (waitpid(api, &status, 0) < 0) { - log_err("Failed to destroy IPCP"); - return -1; - } - return 0; } diff --git a/src/irmd/irm_flow.c b/src/irmd/irm_flow.c index 99966561..4e7c22ef 100644 --- a/src/irmd/irm_flow.c +++ b/src/irmd/irm_flow.c @@ -45,6 +45,7 @@ struct irm_flow * irm_flow_create(pid_t n_api, } if (pthread_mutex_init(&f->state_lock, NULL)) { + pthread_cond_destroy(&f->state_cond); free(f); return NULL; } @@ -63,6 +64,9 @@ struct irm_flow * irm_flow_create(pid_t n_api, f->n_1_rb = shm_rbuff_create(n_1_api, port_id); if (f->n_1_rb == NULL) { log_err("Could not create ringbuffer for AP-I %d.", n_1_api); + shm_rbuff_destroy(f->n_rb); + pthread_mutex_destroy(&f->state_lock); + pthread_cond_destroy(&f->state_cond); free(f); return NULL; } @@ -122,7 +126,8 @@ enum flow_state irm_flow_get_state(struct irm_flow * f) return state; } -void irm_flow_set_state(struct irm_flow * f, enum flow_state state) +void irm_flow_set_state(struct irm_flow * f, + enum flow_state state) { assert(f); assert(state != FLOW_DESTROY); @@ -135,7 +140,8 @@ void irm_flow_set_state(struct irm_flow * f, enum flow_state state) pthread_mutex_unlock(&f->state_lock); } -enum flow_state irm_flow_wait_state(struct irm_flow * f, enum flow_state state) +enum flow_state irm_flow_wait_state(struct irm_flow * f, + enum flow_state state) { assert(f); assert(state != FLOW_NULL); @@ -143,6 +149,8 @@ enum flow_state irm_flow_wait_state(struct irm_flow * f, enum flow_state state) pthread_mutex_lock(&f->state_lock); + assert(f->state != FLOW_NULL); + while (!(f->state == state || f->state == FLOW_DESTROY)) pthread_cond_wait(&f->state_cond, &f->state_lock); diff --git a/src/irmd/main.c b/src/irmd/main.c index 9901a608..c7adf386 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -133,7 +133,8 @@ static struct irm_flow * get_irm_flow_n(pid_t n_api) list_for_each(pos, &irmd->irm_flows) { struct irm_flow * e = list_entry(pos, struct irm_flow, next); - if (e->n_api == n_api) + if (e->n_api == n_api && + irm_flow_get_state(e) == FLOW_ALLOC_PENDING) return e; } @@ -982,7 +983,12 @@ static struct irm_flow * flow_accept(pid_t api, struct irm_flow * f = NULL; struct api_entry * e = NULL; struct reg_entry * re = NULL; - struct list_head * p; + struct list_head * p = NULL; + + pid_t api_n1; + pid_t api_n; + int port_id; + int ret; pthread_rwlock_rdlock(&irmd->state_lock); @@ -1016,7 +1022,7 @@ static struct irm_flow * flow_accept(pid_t api, pthread_rwlock_unlock(&irmd->reg_lock); pthread_rwlock_unlock(&irmd->state_lock); - while (api_entry_sleep(e) == -ETIMEDOUT) { + while ((ret = api_entry_sleep(e)) == -ETIMEDOUT) { pthread_rwlock_rdlock(&irmd->state_lock); if (irmd->state != IRMD_RUNNING) { pthread_rwlock_unlock(&irmd->state_lock); @@ -1025,126 +1031,76 @@ static struct irm_flow * flow_accept(pid_t api, pthread_rwlock_unlock(&irmd->state_lock); } - pthread_rwlock_rdlock(&irmd->state_lock); - - if (irmd->state != IRMD_RUNNING) { - reg_entry_set_state(re, REG_NAME_NULL); - pthread_rwlock_unlock(&irmd->state_lock); + if (ret == -1) { + /* The process died, we can exit here. */ return NULL; } - pthread_rwlock_rdlock(&irmd->reg_lock); + pthread_rwlock_rdlock(&irmd->state_lock); - e = api_table_get(&irmd->api_table, api); - if (e == NULL) { - pthread_rwlock_unlock(&irmd->reg_lock); + if (irmd->state != IRMD_RUNNING) { + reg_entry_set_state(re, REG_NAME_NULL); pthread_rwlock_unlock(&irmd->state_lock); - log_dbg("Process gone while accepting flow."); return NULL; } - pthread_mutex_lock(&e->state_lock); - - re = e->re; - - pthread_mutex_unlock(&e->state_lock); - - if (reg_entry_get_state(re) != REG_NAME_FLOW_ARRIVED) { - pthread_rwlock_unlock(&irmd->reg_lock); - pthread_rwlock_unlock(&irmd->state_lock); - log_err("Entry in wrong state."); - return NULL; - } - pthread_rwlock_unlock(&irmd->reg_lock); pthread_rwlock_rdlock(&irmd->flows_lock); 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."); + log_warn("Port_id was not created yet."); return NULL; } *cube = re->qos; + api_n = f->n_api; + api_n1 = f->n_1_api; + port_id = f->port_id; + log_info("Flow on port_id %d allocated.", f->port_id); pthread_rwlock_unlock(&irmd->flows_lock); - pthread_rwlock_unlock(&irmd->state_lock); - - return f; -} - -static int flow_alloc_resp(pid_t n_api, - int port_id, - int response) -{ - struct irm_flow * f = NULL; - struct reg_entry * re = NULL; - struct api_entry * e = NULL; - int ret = -1; - - pid_t api_n1; - pid_t api_n; - - pthread_rwlock_rdlock(&irmd->state_lock); - - if (irmd->state != IRMD_RUNNING) { - pthread_rwlock_unlock(&irmd->state_lock); - return -1; - } - - pthread_rwlock_wrlock(&irmd->reg_lock); + pthread_rwlock_rdlock(&irmd->reg_lock); - e = api_table_get(&irmd->api_table, n_api); + e = api_table_get(&irmd->api_table, api); if (e == NULL) { pthread_rwlock_unlock(&irmd->reg_lock); pthread_rwlock_unlock(&irmd->state_lock); - log_err("Unknown AP-I %d responding for port_id %d.", - n_api, port_id); - return -1; + ipcp_flow_alloc_resp(api_n1, port_id, api_n, -1); + log_dbg("Process gone while accepting flow."); + return NULL; } + pthread_mutex_lock(&e->state_lock); + re = e->re; - if (re == NULL) { - pthread_rwlock_unlock(&irmd->reg_lock); - pthread_rwlock_unlock(&irmd->state_lock); - log_err("AP-I %d is not handling a flow request.", n_api); - return -1; - } + + pthread_mutex_unlock(&e->state_lock); if (reg_entry_get_state(re) != REG_NAME_FLOW_ARRIVED) { pthread_rwlock_unlock(&irmd->reg_lock); pthread_rwlock_unlock(&irmd->state_lock); - log_err("Name %s has no pending flow request.", re->name); - return -1; + ipcp_flow_alloc_resp(api_n1, port_id, api_n, -1); + log_err("Entry in wrong state."); + return NULL; } - registry_del_api(&irmd->registry, n_api); + registry_del_api(&irmd->registry, api); pthread_rwlock_unlock(&irmd->reg_lock); - pthread_rwlock_wrlock(&irmd->flows_lock); - - f = get_irm_flow(port_id); - if (f == NULL) { - pthread_rwlock_unlock(&irmd->flows_lock); - pthread_rwlock_unlock(&irmd->state_lock); - return -1; - } - - api_n = f->n_api; - api_n1 = f->n_1_api; - - pthread_rwlock_unlock(&irmd->flows_lock); pthread_rwlock_unlock(&irmd->state_lock); - ret = ipcp_flow_alloc_resp(api_n1, port_id, api_n, response); + if (ipcp_flow_alloc_resp(api_n1, port_id, api_n, 0)) { + log_dbg("Failed to respond to alloc."); + return NULL; + } - if (!(response || ret)) - irm_flow_set_state(f, FLOW_ALLOCATED); + irm_flow_set_state(f, FLOW_ALLOCATED); - return ret; + return f; } static struct irm_flow * flow_alloc(pid_t api, @@ -1196,6 +1152,8 @@ static struct irm_flow * flow_alloc(pid_t api, pthread_rwlock_unlock(&irmd->flows_lock); pthread_rwlock_unlock(&irmd->state_lock); + assert(irm_flow_get_state(f) == FLOW_ALLOC_PENDING); + if (ipcp_flow_alloc(ipcp, port_id, api, dst_name, cube) < 0) { pthread_rwlock_rdlock(&irmd->state_lock); @@ -1210,54 +1168,16 @@ static struct irm_flow * flow_alloc(pid_t api, return NULL; } - return f; -} - -static int flow_alloc_res(int port_id) -{ - struct irm_flow * f; - - pthread_rwlock_rdlock(&irmd->state_lock); - - if (irmd->state != IRMD_RUNNING) { - pthread_rwlock_unlock(&irmd->state_lock); - return -1; - } - pthread_rwlock_rdlock(&irmd->flows_lock); - - f = get_irm_flow(port_id); - if (f == NULL) { - pthread_rwlock_unlock(&irmd->flows_lock); - pthread_rwlock_unlock(&irmd->state_lock); - log_err("Could not find port %d.", port_id); - return -1; - } - - if (irm_flow_get_state(f) == FLOW_NULL) { - pthread_rwlock_unlock(&irmd->flows_lock); - pthread_rwlock_unlock(&irmd->state_lock); - log_info("Port %d is deprecated.", port_id); - return -1; - } - - if (irm_flow_get_state(f) == FLOW_ALLOCATED) { - log_info("Flow on port_id %d allocated.", port_id); - pthread_rwlock_unlock(&irmd->flows_lock); - pthread_rwlock_unlock(&irmd->state_lock); - return 0; + if (irm_flow_wait_state(f, FLOW_ALLOCATED) != FLOW_ALLOCATED) { + log_info("Pending flow on port_id %d torn down.", port_id); + return NULL; } - pthread_rwlock_unlock(&irmd->flows_lock); - pthread_rwlock_unlock(&irmd->state_lock); - - if (irm_flow_wait_state(f, FLOW_ALLOCATED) == FLOW_ALLOCATED) { - log_info("Flow on port_id %d allocated.", port_id); - return 0; - } + assert(irm_flow_get_state(f) == FLOW_ALLOCATED); - log_info("Pending flow on port_id %d torn down.", port_id); + log_info("Flow on port_id %d allocated.", port_id); - return -1; + return f; } static int flow_dealloc(pid_t api, @@ -1293,6 +1213,9 @@ static int flow_dealloc(pid_t api, if (irm_flow_get_state(f) == FLOW_DEALLOC_PENDING) { list_del(&f->next); + if ((kill(f->n_api, 0) < 0 && f->n_1_api == -1) || + (kill (f->n_1_api, 0) < 0 && f->n_api == -1)) + irm_flow_set_state(f, FLOW_NULL); clear_irm_flow(f); irm_flow_destroy(f); bmp_release(irmd->port_ids, port_id); @@ -1305,12 +1228,11 @@ static int flow_dealloc(pid_t api, } pthread_rwlock_unlock(&irmd->flows_lock); + pthread_rwlock_unlock(&irmd->state_lock); if (n_1_api != -1) ret = ipcp_flow_dealloc(n_1_api, port_id); - pthread_rwlock_unlock(&irmd->state_lock); - return ret; } @@ -1501,7 +1423,7 @@ static int flow_alloc_reply(int port_id, struct irm_flow * f; pthread_rwlock_rdlock(&irmd->state_lock); - pthread_rwlock_wrlock(&irmd->flows_lock); + pthread_rwlock_rdlock(&irmd->flows_lock); f = get_irm_flow(port_id); if (f == NULL) { @@ -1551,18 +1473,19 @@ static void irm_destroy(void) list_for_each_safe(p, h, &irmd->ipcps) { struct ipcp_entry * e = list_entry(p, struct ipcp_entry, next); list_del(&e->next); - ipcp_destroy(e->api); - clear_spawned_api(e->api); - registry_del_api(&irmd->registry, e->api); ipcp_entry_destroy(e); } - list_for_each_safe(p, h, &irmd->spawned_apis) { + list_for_each(p, &irmd->spawned_apis) { struct pid_el * e = list_entry(p, struct pid_el, next); - int status; if (kill(e->pid, SIGTERM)) log_dbg("Could not send kill signal to %d.", e->pid); - else if (waitpid(e->pid, &status, 0) < 0) + } + + list_for_each_safe(p, h, &irmd->spawned_apis) { + struct pid_el * e = list_entry(p, struct pid_el, next); + int status; + if (waitpid(e->pid, &status, 0) < 0) log_dbg("Error waiting for %d to exit.", e->pid); list_del(&e->next); registry_del_api(&irmd->registry, e->pid); @@ -1940,12 +1863,6 @@ void * mainloop(void * o) ret_msg.has_api = true; ret_msg.api = e->n_1_api; break; - case IRM_MSG_CODE__IRM_FLOW_ALLOC_RESP: - ret_msg.has_result = true; - ret_msg.result = flow_alloc_resp(msg->api, - msg->port_id, - msg->response); - break; case IRM_MSG_CODE__IRM_FLOW_ALLOC: e = flow_alloc(msg->api, msg->dst_name, @@ -1960,10 +1877,6 @@ void * mainloop(void * o) ret_msg.has_api = true; ret_msg.api = e->n_1_api; break; - case IRM_MSG_CODE__IRM_FLOW_ALLOC_RES: - ret_msg.has_result = true; - ret_msg.result = flow_alloc_res(msg->port_id); - break; case IRM_MSG_CODE__IRM_FLOW_DEALLOC: ret_msg.has_result = true; ret_msg.result = flow_dealloc(msg->api, msg->port_id); |