From ef11d3b677ddcaaf8ca1e42e40579c3773bc9a99 Mon Sep 17 00:00:00 2001 From: evgeny Date: Thu, 22 Oct 2026 22:36:53 +0200 Subject: [PATCH] Preserve initial readiness while sender waits for a session --- src/transport_layer/etcp.c | 2 +- tests/test_etcp_windows.c | 27 ++++++++++++++++++--------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/transport_layer/etcp.c b/src/transport_layer/etcp.c index 9f7537a1..5b68e4bc 100644 --- a/src/transport_layer/etcp.c +++ b/src/transport_layer/etcp.c @@ -1234,7 +1234,7 @@ struct ETCP_DGRAM* etcp_request_pkt(struct ETCP_CONN* etcp) { if (!etcp) return NULL; if (etcp->state == 2) { DEBUG_WARN(DEBUG_CATEGORY_ETCP, "[%s] request_pkt on deleted conn", etcp->log_name); return NULL; } if (etcp->close_requested || !etcp->initialized || etcp->session_required || etcp->reinit_pending) { - etcp->tx_state = ETCP_TX_STATE_LINK_WAIT; + if (etcp->tx_state) etcp->tx_state = ETCP_TX_STATE_LINK_WAIT; return NULL; } if (!etcp->input_send_q->head) input_queue_try_push(etcp); diff --git a/tests/test_etcp_windows.c b/tests/test_etcp_windows.c index 0afcdad2..a8dfeacc 100644 --- a/tests/test_etcp_windows.c +++ b/tests/test_etcp_windows.c @@ -122,6 +122,15 @@ static void ack_all(void) { while (conn->input_wait_ack->head) ack(((struct INFLIGHT_PACKET*)conn->input_wait_ack->head)->seq); } +/* Ждём наблюдаемое событие, а не точную границу миллисекундного таймера uasync. */ +static void wait_sends(unsigned expected) { + uint64_t end = get_time_tb() + 20000; + while (sends < expected && get_time_tb() < end) test_clock_poll(ua, 1); + DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "TX observed=%u expected=%u send_q=%d wait_ack=%d", sends, expected, + conn->input_send_q->count, conn->input_wait_ack->count); + CHECK(sends == expected); check_accounting(); +} + /* В полном пути свободное окно другого линка не разрешает DATA через заполненный. */ static void selection(void) { setup(); fill(a, 8, 1024); fill(b, 16, 1024); a->inflight_lim_bytes = 8192; @@ -162,7 +171,7 @@ static void late_ack_and_migration(void) { check_accounting(); CHECK(!conn->input_wait_ack->count && !a->inflight_bytes); ack(1); ack(1); CHECK(!a->inflight_bytes); b->link_status = 1; etcp_link_update_inflight_lim(b, 8192); - test_clock_run_for(ua, 10); + wait_sends(8); CHECK(!conn->input_send_q->count && b->inflight_bytes == 7768 && sends == 8); for (struct ll_entry* e = conn->input_wait_ack->head; e; e = e->next) CHECK(((struct INFLIGHT_PACKET*)e)->last_link == b); @@ -173,11 +182,11 @@ static void lost_ack_and_shrink(void) { setup(); b->link_status = 0; a->inflight_lim_bytes = 16384; fill(a, 16, 1024); etcp_link_update_inflight_lim(a, 8192); enqueue(1024); CHECK(!request() && a->inflight_bytes == 16384); - test_clock_run_for(ua, 70); + wait_sends(8); check_accounting(); CHECK(sends == 8 && a->inflight_bytes == 8192 && conn->input_send_q->count == 9); - ack_all(); test_clock_run_for(ua, 10); + ack_all(); wait_sends(16); CHECK(sends == 16 && a->inflight_bytes == 8192 && conn->input_send_q->count == 1); - ack_all(); test_clock_run_for(ua, 10); ack_all(); + ack_all(); wait_sends(17); ack_all(); CHECK(!conn->unacked_bytes && !conn->input_send_q->count); teardown(); } @@ -187,22 +196,22 @@ static void grow_and_session(void) { CHECK(!request()); uint64_t allocated = ua->timer_alloc_count; test_clock_run_for(ua, 20); CHECK(!sends && ua->timer_alloc_count - allocated < 4); - etcp_link_update_inflight_lim(a, 16384); test_clock_run_for(ua, 10); + etcp_link_update_inflight_lim(a, 16384); wait_sends(1); CHECK(sends == 1 && a->inflight_bytes == 8292); ack_all(); conn->initialized = 0; conn->session_required = conn->reinit_pending = 1; enqueue(100); CHECK(!request()); test_clock_run_for(ua, 10); CHECK(sends == 1); - conn->session_required = 0; etcp_conn_ready(conn); test_clock_run_for(ua, 10); + conn->session_required = 0; etcp_conn_ready(conn); wait_sends(2); CHECK(sends == 2 && conn->input_wait_ack->count == 1); ack_all(); teardown(); } static void allocation_and_send_failure(void) { setup(); b->link_status = 0; enqueue(100); fail_alloc = 1; - test_clock_run_for(ua, 10); + test_clock_run_for(ua, 20); CHECK(!sends && conn->input_send_q->count == 1 && !a->inflight_bytes && conn->tx_timer); - fail_send = 1; test_clock_run_for(ua, 110); + fail_send = 1; wait_sends(1); CHECK(sends == 1 && conn->input_wait_ack->count == 1); - test_clock_run_for(ua, 70); CHECK(sends == 2); + wait_sends(2); ack_all(); teardown(); }