diff --git a/src/modules/discovery/discovery.c b/src/modules/discovery/discovery.c index f0f3319..11ed374 100644 --- a/src/modules/discovery/discovery.c +++ b/src/modules/discovery/discovery.c @@ -40,6 +40,7 @@ struct Discovery { pthread_t announce_thread; pthread_t receive_thread; atomic_int running; + atomic_int early_announce; /* set when a new peer is seen */ pthread_mutex_t peers_mutex; struct Peer_Entry peers[DISCOVERY_MAX_PEERS]; @@ -131,9 +132,11 @@ static void *announce_thread_fn(void *arg) { send_announcement(d); while (atomic_load(&d->running)) { - /* sleep in 100 ms increments so destroy doesn't wait a full interval */ + /* sleep in 100 ms increments; breaks early if a new peer is detected + * or if destroy is called */ uint32_t elapsed = 0; while (atomic_load(&d->running) && elapsed < d->config.interval_ms) { + if (atomic_load(&d->early_announce)) { break; } struct timespec ts = { .tv_sec = 0, .tv_nsec = 100 * 1000000L }; nanosleep(&ts, NULL); elapsed += 100; @@ -141,6 +144,7 @@ static void *announce_thread_fn(void *arg) { if (!atomic_load(&d->running)) { break; } + atomic_store(&d->early_announce, 0); send_announcement(d); check_timeouts(d); } @@ -224,8 +228,11 @@ static void *receive_thread_fn(void *arg) { pthread_mutex_unlock(&d->peers_mutex); - if (is_new && d->config.on_peer_found) { - d->config.on_peer_found(&peer_copy, d->config.userdata); + if (is_new) { + atomic_store(&d->early_announce, 1); + if (d->config.on_peer_found) { + d->config.on_peer_found(&peer_copy, d->config.userdata); + } } } @@ -255,6 +262,7 @@ struct App_Error discovery_create(struct Discovery **out, inet_pton(AF_INET, DISCOVERY_MULTICAST_GROUP, &d->mcast_addr.sin_addr); atomic_init(&d->running, 0); + atomic_init(&d->early_announce, 0); pthread_mutex_init(&d->peers_mutex, NULL); *out = d;