summaryrefslogtreecommitdiff
path: root/src/irmd/main.c
diff options
context:
space:
mode:
authordimitri staessens <dimitri.staessens@intec.ugent.be>2017-02-12 16:15:46 +0100
committerdimitri staessens <dimitri.staessens@intec.ugent.be>2017-02-12 22:19:50 +0100
commit98a15feabb6a14e52a54a09dfed58d55e0f99884 (patch)
tree0a67e3eb076558b6408d5744d74808e756e0639d /src/irmd/main.c
parent2ee140ec27335ca50e813080ee0e85e4ab86af37 (diff)
downloadouroboros-98a15feabb6a14e52a54a09dfed58d55e0f99884.tar.gz
ouroboros-98a15feabb6a14e52a54a09dfed58d55e0f99884.zip
irmd: Allow time for AP to call flow_accept()
When there is a burst of successive flow allocations for a certain name, each such request will block a thread in the IRMD for IRMD_REQ_ARR_TIMEOUT ms to allow the application some time to respond. This refactors some parts of the IRMd.
Diffstat (limited to 'src/irmd/main.c')
-rw-r--r--src/irmd/main.c45
1 files changed, 29 insertions, 16 deletions
diff --git a/src/irmd/main.c b/src/irmd/main.c
index 2454a9ca..aa4614c1 100644
--- a/src/irmd/main.c
+++ b/src/irmd/main.c
@@ -970,7 +970,6 @@ static struct irm_flow * flow_accept(pid_t api,
log_err("Unknown instance %d calling accept.", api);
return NULL;
}
-
log_dbg("New instance (%d) of %s added.", api, e->apn);
log_dbg("This instance accepts flows for:");
list_for_each(p, &e->names) {
@@ -996,6 +995,7 @@ static struct irm_flow * flow_accept(pid_t api,
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);
return NULL;
}
@@ -1331,11 +1331,14 @@ static struct irm_flow * flow_req_arr(pid_t api,
pid_t h_api = -1;
int port_id = -1;
+ struct timespec wt = {IRMD_REQ_ARR_TIMEOUT % 1000,
+ (IRMD_REQ_ARR_TIMEOUT % 1000) * MILLION};
+
log_dbg("Flow req arrived from IPCP %d for %s on AE %s.",
api, dst_name, ae_name);
pthread_rwlock_rdlock(&irmd->state_lock);
- pthread_rwlock_wrlock(&irmd->reg_lock);
+ pthread_rwlock_rdlock(&irmd->reg_lock);
re = registry_get_entry(&irmd->registry, dst_name);
if (re == NULL) {
@@ -1345,6 +1348,18 @@ static struct irm_flow * flow_req_arr(pid_t api,
return NULL;
}
+ pthread_rwlock_unlock(&irmd->reg_lock);
+ pthread_rwlock_unlock(&irmd->state_lock);
+
+ /* Give the AP a bit of slop time to call accept */
+ if (reg_entry_leave_state(re, REG_NAME_IDLE, &wt) == -1) {
+ log_err("No APs for %s.", dst_name);
+ return NULL;
+ }
+
+ pthread_rwlock_rdlock(&irmd->state_lock);
+ pthread_rwlock_wrlock(&irmd->reg_lock);
+
switch (reg_entry_get_state(re)) {
case REG_NAME_IDLE:
pthread_rwlock_unlock(&irmd->reg_lock);
@@ -1378,17 +1393,12 @@ static struct irm_flow * flow_req_arr(pid_t api,
pthread_rwlock_unlock(&irmd->reg_lock);
pthread_rwlock_unlock(&irmd->state_lock);
- reg_entry_leave_state(re, REG_NAME_AUTO_EXEC);
-
- pthread_rwlock_rdlock(&irmd->state_lock);
- pthread_rwlock_rdlock(&irmd->reg_lock);
-
- if (reg_entry_get_state(re) == REG_NAME_DESTROY) {
- reg_entry_set_state(re, REG_NAME_NULL);
+ if (reg_entry_leave_state(re, REG_NAME_AUTO_EXEC, NULL)) {
pthread_rwlock_unlock(&irmd->reg_lock);
pthread_rwlock_unlock(&irmd->state_lock);
return NULL;
}
+
case REG_NAME_FLOW_ACCEPT:
h_api = reg_entry_get_api(re);
if (h_api == -1) {
@@ -1453,7 +1463,7 @@ static struct irm_flow * flow_req_arr(pid_t api,
pthread_rwlock_unlock(&irmd->reg_lock);
pthread_rwlock_unlock(&irmd->state_lock);
- reg_entry_leave_state(re, REG_NAME_FLOW_ARRIVED);
+ reg_entry_leave_state(re, REG_NAME_FLOW_ARRIVED, NULL);
return f;
}
@@ -1518,10 +1528,16 @@ static void irm_destroy(void)
list_del(&e->next);
ipcp_destroy(e->api);
clear_spawned_api(e->api);
+ registry_del_api(&irmd->registry, e->api);
ipcp_entry_destroy(e);
}
- registry_destroy(&irmd->registry);
+ list_for_each_safe(p, h, &irmd->api_table) {
+ struct api_entry * e = list_entry(p, struct api_entry, next);
+ list_del(&e->next);
+ registry_del_api(&irmd->registry, e->api);
+ api_entry_destroy(e);
+ }
list_for_each_safe(p, h, &irmd->spawned_apis) {
struct pid_el * e = list_entry(p, struct pid_el, next);
@@ -1531,6 +1547,7 @@ static void irm_destroy(void)
else 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);
free(e);
}
@@ -1540,11 +1557,7 @@ static void irm_destroy(void)
apn_entry_destroy(e);
}
- list_for_each_safe(p, h, &irmd->api_table) {
- struct api_entry * e = list_entry(p, struct api_entry, next);
- list_del(&e->next);
- api_entry_destroy(e);
- }
+ registry_destroy(&irmd->registry);
pthread_rwlock_unlock(&irmd->reg_lock);