From e1c0714d5827cd927961f3a687d9720e6e9aa802 Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Wed, 5 Apr 2017 20:02:28 +0200 Subject: lib, irmd: Implement flow allocation timeout Setting the timeouts on flow_alloc and flow_accept will now work. This makes some changes to the UNIX sockets used for management communication between the APs, IRMd and IPCPs. --- src/irmd/api_table.c | 85 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 55 insertions(+), 30 deletions(-) (limited to 'src/irmd/api_table.c') diff --git a/src/irmd/api_table.c b/src/irmd/api_table.c index 5ff0fcf6..268f8231 100644 --- a/src/irmd/api_table.c +++ b/src/irmd/api_table.c @@ -31,14 +31,17 @@ #include #include #include +#include -struct api_entry * api_entry_create(pid_t api, char * apn) +#define ENTRY_SLEEP_TIMEOUT 10 /* ms */ + +struct api_entry * api_entry_create(pid_t api, + char * apn) { struct api_entry * e; pthread_condattr_t cattr; - if (apn == NULL) - return NULL; + assert(apn); e = malloc(sizeof(*e)); if (e == NULL) @@ -84,8 +87,7 @@ void api_entry_destroy(struct api_entry * e) struct list_head * p; struct list_head * h; - if (e == NULL) - return; + assert(e); pthread_mutex_lock(&e->state_lock); @@ -121,11 +123,13 @@ void api_entry_destroy(struct api_entry * e) free(e); } -int api_entry_add_name(struct api_entry * e, char * name) +int api_entry_add_name(struct api_entry * e, + char * name) { struct str_el * s; - if (e == NULL || name == NULL) - return -EINVAL; + + assert(e); + assert(name); s = malloc(sizeof(*s)); if (s == NULL) @@ -137,11 +141,15 @@ int api_entry_add_name(struct api_entry * e, char * name) return 0; } -void api_entry_del_name(struct api_entry * e, char * name) +void api_entry_del_name(struct api_entry * e, + char * name) { struct list_head * p = NULL; struct list_head * h = NULL; + assert(e); + assert(name); + list_for_each_safe(p, h, &e->names) { struct str_el * s = list_entry(p, struct str_el, next); if (!wildcard_match(name, s->str)) { @@ -153,31 +161,34 @@ void api_entry_del_name(struct api_entry * e, char * name) } } +void api_entry_cancel(struct api_entry * e) +{ + pthread_mutex_lock(&e->state_lock); + + e->state = API_INIT; + pthread_cond_broadcast(&e->state_cond); + + pthread_mutex_unlock(&e->state_lock); +} + int api_entry_sleep(struct api_entry * e) { - struct timespec timeout = {(IRMD_ACCEPT_TIMEOUT / 1000), - (IRMD_ACCEPT_TIMEOUT % 1000) * MILLION}; + struct timespec timeout = {(ENTRY_SLEEP_TIMEOUT / 1000), + (ENTRY_SLEEP_TIMEOUT % 1000) * MILLION}; struct timespec now; struct timespec dl; int ret = 0; - if (e == NULL) - return -EINVAL; - - e->re = NULL; + assert(e); clock_gettime(PTHREAD_COND_CLOCK, &now); - ts_add(&now, &timeout, &dl); pthread_mutex_lock(&e->state_lock); - if (e->state != API_INIT) { - pthread_mutex_unlock(&e->state_lock); - return -EINVAL; - } - e->state = API_SLEEP; + if (e->state != API_WAKE && e->state != API_DESTROY) + e->state = API_SLEEP; while (e->state == API_SLEEP && ret != -ETIMEDOUT) ret = -pthread_cond_timedwait(&e->state_cond, @@ -190,17 +201,20 @@ int api_entry_sleep(struct api_entry * e) ret = -1; } - e->state = API_INIT; + if (ret != -ETIMEDOUT) + e->state = API_INIT; + pthread_cond_broadcast(&e->state_cond); pthread_mutex_unlock(&e->state_lock); return ret; } -void api_entry_wake(struct api_entry * e, struct reg_entry * re) +void api_entry_wake(struct api_entry * e, + struct reg_entry * re) { - if (e == NULL) - return; + assert(e); + assert(re); pthread_mutex_lock(&e->state_lock); @@ -217,24 +231,32 @@ void api_entry_wake(struct api_entry * e, struct reg_entry * re) while (e->state == API_WAKE) pthread_cond_wait(&e->state_cond, &e->state_lock); + if (e->state == API_DESTROY) + e->state = API_INIT; + pthread_mutex_unlock(&e->state_lock); } -int api_table_add(struct list_head * api_table, struct api_entry * e) +int api_table_add(struct list_head * api_table, + struct api_entry * e) { - if (api_table == NULL || e == NULL) - return -EINVAL; + + assert(api_table); + assert(e); list_add(&e->next, api_table); return 0; } -void api_table_del(struct list_head * api_table, pid_t api) +void api_table_del(struct list_head * api_table, + pid_t api) { struct list_head * p; struct list_head * h; + assert(api_table); + list_for_each_safe(p, h, api_table) { struct api_entry * e = list_entry(p, struct api_entry, next); if (api == e->api) { @@ -244,10 +266,13 @@ void api_table_del(struct list_head * api_table, pid_t api) } } -struct api_entry * api_table_get(struct list_head * api_table, pid_t api) +struct api_entry * api_table_get(struct list_head * api_table, + pid_t api) { struct list_head * h; + assert(api_table); + list_for_each(h, api_table) { struct api_entry * e = list_entry(h, struct api_entry, next); if (api == e->api) -- cgit v1.2.3