fix: capture SSL_get_error once per retry; lock ha->lock in ha_check_priority_stepdown

This commit is contained in:
Rongsong Shen 2026-05-13 16:44:55 +00:00
parent fe3cc57f27
commit ec3cab40c3

View file

@ -186,10 +186,13 @@ static void *probe_thread(void *arg)
int sr;
do {
sr = SSL_connect(ssl);
} while (sr <= 0 &&
(SSL_get_error(ssl, sr) == SSL_ERROR_WANT_READ ||
SSL_get_error(ssl, sr) == SSL_ERROR_WANT_WRITE) &&
!atomic_load(ctx->election_done));
if (sr <= 0) {
int ssl_err = SSL_get_error(ssl, sr);
if (ssl_err != SSL_ERROR_WANT_READ &&
ssl_err != SSL_ERROR_WANT_WRITE)
break;
}
} while (sr <= 0 && !atomic_load(ctx->election_done));
SSL_shutdown(ssl);
SSL_free(ssl);
if (sr <= 0 || atomic_load(ctx->election_done))
@ -326,13 +329,21 @@ void ha_check_priority_stepdown(ha_state_t *ha, int sender_priority,
if (my_term > 0 || sender_term > 0)
return; /* term-based election took over — don't interfere */
ctrl_role_t role = (ctrl_role_t)atomic_load_explicit(&ha->role,
memory_order_acquire);
if (role == CTRL_PRIMARY) {
WARN("HA: stepping down — higher-priority peer (priority=%d) present at term=0",
sender_priority);
ha_do_demote(ha);
/* Hold lock to make the role-check + demote atomic, preventing a
* concurrent promotion from racing between the two operations. */
pthread_mutex_lock(&ha->lock);
/* Re-check term under lock in case a concurrent promotion raced us */
my_term = atomic_load_explicit(&ha->term, memory_order_acquire);
if (my_term == 0 && sender_term == 0) {
ctrl_role_t role = (ctrl_role_t)atomic_load_explicit(&ha->role,
memory_order_acquire);
if (role == CTRL_PRIMARY) {
WARN("HA: stepping down — higher-priority peer (priority=%d) at term=0",
sender_priority);
ha_do_demote(ha);
}
}
pthread_mutex_unlock(&ha->lock);
}
/*