summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Staessens <dimitri.staessens@ugent.be>2018-05-03 14:19:49 +0200
committerSander Vrijders <sander.vrijders@ugent.be>2018-05-03 14:35:08 +0200
commit04aa4e185cbd7d165bcd2f5855f624bc0569d24b (patch)
tree50791d20be1eb828dd2804eed56874b7d2a93bc4
parent12968ba98642bd7057e8e7f41e184ab2d61671ed (diff)
downloadouroboros-04aa4e185cbd7d165bcd2f5855f624bc0569d24b.tar.gz
ouroboros-04aa4e185cbd7d165bcd2f5855f624bc0569d24b.zip
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 <dimitri.staessens@ugent.be> Signed-off-by: Sander Vrijders <sander.vrijders@ugent.be>
-rw-r--r--src/ipcpd/normal/dht.c46
1 files 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:
/*