Check radio timer ownership through public service lifecycle

This commit is contained in:
evgeny committed 2026-10-19 14:14:52 +02:00
1 parent c0626e0387
commit 04acb6f836
1 file changed
+16 -5
+16 -5
View File
@@ -134,16 +134,27 @@ static void radio_action(struct UTUN_INSTANCE* inst, uint64_t id, int action, ui
radio_call_execute(&req);
}
static int radio_invitation_timers(struct UASYNC* ua) {
static int active_timer_count(struct UASYNC* ua) {
int count = 0;
for (size_t i = 0; i < ua->timeout_heap->size; ++i) {
TimeoutEntry* entry = &ua->timeout_heap->heap[i];
struct timeout_node* node = entry->data;
if (!entry->deleted && node && node->name && !strcmp(node->name, "radio_call")) ++count;
if (!entry->deleted) ++count;
}
return count;
}
/* Публичный lifecycle: idle destroy/init не должен удалять или создавать ни одного таймера. */
static int check_radio_idle_timers(struct rad_ctx* t) {
int before = active_timer_count(t->ua);
for (int i = 0; i < 3; ++i) radio_call_destroy(t->inst[i]);
int stopped = active_timer_count(t->ua);
for (int i = 0; i < 3; ++i) if (radio_call_init(t->inst[i])) return 0;
int restarted = active_timer_count(t->ua);
if (before == stopped && stopped == restarted) return 1;
DEBUG_ERROR(DEBUG_CATEGORY_RADIO, "test idle radio timers before=%d stopped=%d restarted=%d", before, stopped, restarted);
return 0;
}
/* Проверяем именно UI-события: self, прямой пир и пир за посредником. */
static void member_event(struct UTUN_INSTANCE* inst, int type, const uint8_t* data, int len) {
if (type == CHAT_EVT_RADIO_CALL) {
@@ -468,7 +479,7 @@ static void rad_tick(void* arg) {
case 0: {
uint8_t key[32];
if (member_sync_verified_ed25519(A, CH_ID, nc, key) || member_sync_verified_ed25519(C, CH_ID, na, key)) break;
if (radio_invitation_timers(t->ua)) {
if (!check_radio_idle_timers(t)) {
DEBUG_ERROR(DEBUG_CATEGORY_RADIO, "test idle radio invitation service has timers");
t->result = 2; uasync_stop(t->ua); return;
}
@@ -582,7 +593,7 @@ static void rad_tick(void* arg) {
break;
case 9:
if (now - t->call_started >= 5000) {
if (radio_invitation_timers(t->ua) || radio_call_busy(A) || radio_call_busy(B) || radio_call_busy(C)) {
if (radio_call_busy(A) || radio_call_busy(B) || radio_call_busy(C) || !check_radio_idle_timers(t)) {
DEBUG_ERROR(DEBUG_CATEGORY_RADIO, "test finished invitations retain timers or busy state");
t->result = 2; uasync_stop(t->ua); return;
}