Trigger early announcement when a new peer is first seen
When the receive thread detects a genuinely new peer it sets early_announce, causing the announce thread to break out of its sleep and send immediately. The new node receives our announcement within ~100ms rather than waiting up to interval_ms. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -40,6 +40,7 @@ struct Discovery {
|
|||||||
pthread_t announce_thread;
|
pthread_t announce_thread;
|
||||||
pthread_t receive_thread;
|
pthread_t receive_thread;
|
||||||
atomic_int running;
|
atomic_int running;
|
||||||
|
atomic_int early_announce; /* set when a new peer is seen */
|
||||||
|
|
||||||
pthread_mutex_t peers_mutex;
|
pthread_mutex_t peers_mutex;
|
||||||
struct Peer_Entry peers[DISCOVERY_MAX_PEERS];
|
struct Peer_Entry peers[DISCOVERY_MAX_PEERS];
|
||||||
@@ -131,9 +132,11 @@ static void *announce_thread_fn(void *arg) {
|
|||||||
send_announcement(d);
|
send_announcement(d);
|
||||||
|
|
||||||
while (atomic_load(&d->running)) {
|
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;
|
uint32_t elapsed = 0;
|
||||||
while (atomic_load(&d->running) && elapsed < d->config.interval_ms) {
|
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 };
|
struct timespec ts = { .tv_sec = 0, .tv_nsec = 100 * 1000000L };
|
||||||
nanosleep(&ts, NULL);
|
nanosleep(&ts, NULL);
|
||||||
elapsed += 100;
|
elapsed += 100;
|
||||||
@@ -141,6 +144,7 @@ static void *announce_thread_fn(void *arg) {
|
|||||||
|
|
||||||
if (!atomic_load(&d->running)) { break; }
|
if (!atomic_load(&d->running)) { break; }
|
||||||
|
|
||||||
|
atomic_store(&d->early_announce, 0);
|
||||||
send_announcement(d);
|
send_announcement(d);
|
||||||
check_timeouts(d);
|
check_timeouts(d);
|
||||||
}
|
}
|
||||||
@@ -224,8 +228,11 @@ static void *receive_thread_fn(void *arg) {
|
|||||||
|
|
||||||
pthread_mutex_unlock(&d->peers_mutex);
|
pthread_mutex_unlock(&d->peers_mutex);
|
||||||
|
|
||||||
if (is_new && d->config.on_peer_found) {
|
if (is_new) {
|
||||||
d->config.on_peer_found(&peer_copy, d->config.userdata);
|
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);
|
inet_pton(AF_INET, DISCOVERY_MULTICAST_GROUP, &d->mcast_addr.sin_addr);
|
||||||
|
|
||||||
atomic_init(&d->running, 0);
|
atomic_init(&d->running, 0);
|
||||||
|
atomic_init(&d->early_announce, 0);
|
||||||
pthread_mutex_init(&d->peers_mutex, NULL);
|
pthread_mutex_init(&d->peers_mutex, NULL);
|
||||||
|
|
||||||
*out = d;
|
*out = d;
|
||||||
|
|||||||
Reference in New Issue
Block a user