From 04aa4e185cbd7d165bcd2f5855f624bc0569d24b Mon Sep 17 00:00:00 2001 From: Dimitri Staessens Date: Thu, 3 May 2018 14:19:49 +0200 Subject: ipcpd: Prevent parallel DHT enrollment threads This will prevent quick calls to ipcp conn for dt flows to create multiple join threads in parallel, instead the subsequent calls will wait for the pending join to finish. Signed-off-by: Dimitri Staessens Signed-off-by: Sander Vrijders --- src/ipcpd/normal/dht.c | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/src/ipcpd/normal/dht.c b/src/ipcpd/normal/dht.c index 1e96c94a..1fabcb84 100644 --- a/src/ipcpd/normal/dht.c +++ b/src/ipcpd/normal/dht.c @@ -276,16 +276,23 @@ static enum dht_state dht_get_state(struct dht * dht) return state; } -static void dht_set_state(struct dht * dht, - enum dht_state state) +static int dht_set_state(struct dht * dht, + enum dht_state state) { pthread_mutex_lock(&dht->mtx); + if (state == DHT_JOINING && dht->state != DHT_INIT) { + pthread_mutex_unlock(&dht->mtx); + return -1; + } + dht->state = state; pthread_cond_broadcast(&dht->cond); pthread_mutex_unlock(&dht->mtx); + + return 0; } static int dht_wait_running(struct dht * dht) @@ -2282,9 +2289,6 @@ int dht_reg(struct dht * dht, assert(key); assert(dht->addr != 0); - if (dht_get_state(dht) < DHT_JOINING) - return -1; - if (dht_wait_running(dht)) return -1; @@ -2353,9 +2357,6 @@ uint64_t dht_query(struct dht * dht, addrs[0] = 0; - if (dht_get_state(dht) < DHT_JOINING) - return 0; - if (dht_wait_running(dht)) return 0; @@ -2715,27 +2716,28 @@ static void handle_event(void * self, if (event == NOTIFY_DT_CONN_ADD) { pthread_t thr; - struct join_info * info; + struct join_info * inf; struct conn * c = (struct conn *) o; - enum dht_state state = dht_get_state(dht); - switch(state) { + switch(dht_get_state(dht)) { case DHT_INIT: - info = malloc(sizeof(*info)); - if (info == NULL) + inf = malloc(sizeof(*inf)); + if (inf == NULL) break; - info->dht = dht; - info->addr = c->conn_info.addr; + inf->dht = dht; + inf->addr = c->conn_info.addr; - dht_set_state(dht, DHT_JOINING); - - if (pthread_create(&thr, NULL, join_thr, info)) { - dht_set_state(dht, DHT_INIT); - free(info); - return; + if (dht_set_state(dht, DHT_JOINING) == 0 || + dht_wait_running(dht)) { + log_dbg("creating join thread."); + if (pthread_create(&thr, NULL, join_thr, inf)) { + dht_set_state(dht, DHT_INIT); + free(inf); + return; + } + pthread_detach(thr); } - pthread_detach(thr); break; case DHT_RUNNING: /* -- cgit v1.2.3