Stop readiness publication after callback close and rescan teardown links
This commit is contained in:
1 parent
f37221107d
commit
4614577d19
2 files changed
+29
-14
No files matched your search
+27
-14
@@ -269,7 +269,12 @@ void etcp_fire_conn_status(struct ETCP_CONN* etcp, int status) {
|
||||
(status >= 0 && status < (int)(sizeof(names)/sizeof(names[0]))) ? names[status] : "?");
|
||||
etcp->callbacks_running++;
|
||||
struct etcp_status_cbk_entry* cbe = etcp->instance->conn_status_cbks;
|
||||
while (cbe) { struct etcp_status_cbk_entry* n = cbe->next; cbe->fn(etcp, status, cbe->arg); cbe = n; }
|
||||
while (cbe) {
|
||||
struct etcp_status_cbk_entry* n = cbe->next;
|
||||
cbe->fn(etcp, status, cbe->arg);
|
||||
if (etcp->close_requested && status != ETCP_CONN_STATUS_DOWN && status != ETCP_CONN_STATUS_DELETE) break;
|
||||
cbe = n;
|
||||
}
|
||||
etcp->callbacks_running--;
|
||||
}
|
||||
|
||||
@@ -281,7 +286,12 @@ void etcp_cbk_fire(struct ETCP_CONN* conn, int event) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[%s] callback event: %s", conn->log_name, (idx >= 0 && idx < (int)(sizeof(names)/sizeof(names[0]))) ? names[idx] : "?");
|
||||
conn->callbacks_running++;
|
||||
struct etcp_cbk_entry* cbe = conn->cbks;
|
||||
while (cbe) { struct etcp_cbk_entry* n = cbe->next; if (cbe->fn && (cbe->event_mask & event)) cbe->fn(conn, event, cbe->arg); cbe = n; }
|
||||
while (cbe) {
|
||||
struct etcp_cbk_entry* n = cbe->next;
|
||||
if (cbe->fn && (cbe->event_mask & event)) cbe->fn(conn, event, cbe->arg);
|
||||
if (conn->close_requested && event != ETCP_CBK_EVENT_DOWN && event != ETCP_CBK_EVENT_DELETE) break;
|
||||
cbe = n;
|
||||
}
|
||||
conn->callbacks_running--;
|
||||
if (!conn->callbacks_running) {
|
||||
struct etcp_cbk_entry** pp = &conn->cbks;
|
||||
@@ -293,7 +303,7 @@ void etcp_cbk_fire(struct ETCP_CONN* conn, int event) {
|
||||
}
|
||||
|
||||
static void etcp_on_up(struct ETCP_CONN* etcp) {
|
||||
if (etcp->state == 2) return; // defensive: после DELETE UP не стреляет
|
||||
if (etcp->state == 2 || etcp->close_requested) return;
|
||||
etcp_down_timer_cancel(etcp);
|
||||
int total_links = 0; for (struct ETCP_LINK* l = etcp->links; l; l = l->next) total_links++;
|
||||
uint64_t elapsed_ms = (get_time_tb() - etcp->setup_start_tb) / 10;
|
||||
@@ -310,7 +320,7 @@ static void etcp_on_up(struct ETCP_CONN* etcp) {
|
||||
strbuf_free(&sb);
|
||||
(void)elapsed_ms;
|
||||
etcp_cbk_fire(etcp, ETCP_CBK_EVENT_UP);
|
||||
etcp_fire_conn_status(etcp, ETCP_CONN_STATUS_UP);
|
||||
if (!etcp->close_requested) etcp_fire_conn_status(etcp, ETCP_CONN_STATUS_UP);
|
||||
}
|
||||
|
||||
static void etcp_on_down(struct ETCP_CONN* etcp, struct ETCP_LINK* down_link) {
|
||||
@@ -328,7 +338,7 @@ static void etcp_on_down(struct ETCP_CONN* etcp, struct ETCP_LINK* down_link) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "[%s] Connection DOWN — closing, links: %s", etcp->log_name, any ? strbuf_str(&sb) : "(none)");
|
||||
strbuf_free(&sb);
|
||||
etcp_cbk_fire(etcp, ETCP_CBK_EVENT_DOWN);
|
||||
etcp_fire_conn_status(etcp, ETCP_CONN_STATUS_DOWN);
|
||||
if (!etcp->close_requested) etcp_fire_conn_status(etcp, ETCP_CONN_STATUS_DOWN);
|
||||
}
|
||||
|
||||
|
||||
@@ -341,9 +351,7 @@ static void etcp_connection_free_resources(struct ETCP_CONN* etcp) {
|
||||
|
||||
// Close links
|
||||
if (etcp->links) {
|
||||
struct ETCP_LINK* link = etcp->links;
|
||||
while (link) { struct ETCP_LINK* next = link->next; etcp_link_close(link); link = next; }
|
||||
etcp->links = NULL;
|
||||
while (etcp->links) etcp_link_close(etcp->links);
|
||||
}
|
||||
|
||||
// Drain and free all queues
|
||||
@@ -443,9 +451,8 @@ void etcp_connection_close(struct ETCP_CONN* etcp) {
|
||||
|
||||
// Close links (detach from socket scan queues)
|
||||
if (etcp->links) {
|
||||
struct ETCP_LINK* link = etcp->links;
|
||||
while (link) { struct ETCP_LINK* next = link->next; etcp_link_close(link); link = next; }
|
||||
etcp->links = NULL;
|
||||
/* Callback закрытия одного пути может удалить соседний: следующий берём заново. */
|
||||
while (etcp->links) etcp_link_close(etcp->links);
|
||||
}
|
||||
|
||||
// Remove from instance queue
|
||||
@@ -582,7 +589,7 @@ void etcp_conn_apply_peer_reset_id(struct ETCP_CONN* conn, uint64_t peer_reset_i
|
||||
|
||||
// внутренняя функция. Вызывается один раз когда первый линк готов.
|
||||
void etcp_conn_ready(struct ETCP_CONN* conn) {
|
||||
if (!conn) return;
|
||||
if (!conn || conn->close_requested) return;
|
||||
if (conn->state == 2) { DEBUG_WARN(DEBUG_CATEGORY_ETCP, "[%s] conn_ready on deleted conn", conn->log_name); return; }
|
||||
if (conn->initialized || conn->session_required) return; // ready or awaiting authenticated confirmation
|
||||
|
||||
@@ -595,6 +602,7 @@ void etcp_conn_ready(struct ETCP_CONN* conn) {
|
||||
for (struct ETCP_LINK* link = conn->links; link; link = link->next)
|
||||
if (link->initialized && link->link_status) conn->links_up = 1;
|
||||
etcp_conn_queue_set_ready(conn);
|
||||
if (conn->close_requested) return;
|
||||
|
||||
// Реинит уже готового соединения (state!=0): etcp_conn_queue_set_ready не сработал
|
||||
// (ранний выход по state!=0), поэтому reinit_pending остаётся висеть и блокирует приём —
|
||||
@@ -602,6 +610,7 @@ void etcp_conn_ready(struct ETCP_CONN* conn) {
|
||||
if (conn->reinit_pending) {
|
||||
conn->reinit_pending = 0;
|
||||
etcp_cbk_fire(conn, ETCP_CBK_EVENT_REINIT);
|
||||
if (conn->close_requested) return;
|
||||
etcp_fire_conn_status(conn, ETCP_CONN_STATUS_REINIT);
|
||||
}
|
||||
if (conn->normalizer && !conn->close_requested) queue_resume_callback(conn->normalizer->input);
|
||||
@@ -646,8 +655,12 @@ void etcp_conn_queue_set_ready(struct ETCP_CONN* conn) {
|
||||
conn->log_name, conn->state, (unsigned long long)conn->peer_node_id);
|
||||
|
||||
etcp_cbk_fire(conn, ETCP_CBK_EVENT_INIT);
|
||||
if (conn->reinit_pending) { conn->reinit_pending = 0; etcp_cbk_fire(conn, ETCP_CBK_EVENT_REINIT);
|
||||
etcp_fire_conn_status(conn, ETCP_CONN_STATUS_REINIT); }
|
||||
if (conn->close_requested) return;
|
||||
if (conn->reinit_pending) {
|
||||
conn->reinit_pending = 0; etcp_cbk_fire(conn, ETCP_CBK_EVENT_REINIT);
|
||||
if (conn->close_requested) return;
|
||||
etcp_fire_conn_status(conn, ETCP_CONN_STATUS_REINIT);
|
||||
}
|
||||
if (conn->links_up) etcp_on_up(conn);
|
||||
}
|
||||
|
||||
|
||||
@@ -94,12 +94,14 @@ void etcp_remove_link_status_cbk(struct UTUN_INSTANCE* inst, etcp_link_status_cb
|
||||
void etcp_fire_link_status_cbk(struct ETCP_LINK* link, int old_state, int old_status) {
|
||||
if (!link || !link->etcp || !link->etcp->instance) return;
|
||||
struct ETCP_CONN* conn = link->etcp;
|
||||
int closing_connection = conn->close_requested;
|
||||
int was_attached = 0;
|
||||
for (struct ETCP_LINK* current = conn->links; current; current = current->next) if (current == link) { was_attached = 1; break; }
|
||||
conn->callbacks_running++;
|
||||
struct etcp_link_status_cbk_entry* cbe = conn->instance->link_status_cbks;
|
||||
while (cbe) {
|
||||
cbe->fn(conn, link, old_state, old_status, cbe->arg);
|
||||
if (!closing_connection && conn->close_requested) break;
|
||||
if (was_attached) {
|
||||
int attached = 0;
|
||||
for (struct ETCP_LINK* current = conn->links; current; current = current->next)
|
||||
|
||||
Reference in new issue
Block a user