Honor core stop before and after Android restart with lifecycle regressions

This commit is contained in:
evgeny committed 2026-10-26 22:07:39 +01:00
1 parent c75bfc618a
commit e5ca2e174c
3 files changed
+20 -6

No files matched your search

@@ -377,9 +377,10 @@ static void* instance_thread(void* arg) {
uasync_mark_running(g_ua);
chat_event_post(g_inst, CHAT_EVT_SERVICE_STARTED, NULL, 0);
while (!__atomic_load_n(&g_stop, __ATOMIC_ACQUIRE)) {
while (!__atomic_load_n(&g_stop, __ATOMIC_ACQUIRE) && g_inst->running) {
uasync_poll(g_ua, -1);
}
if (!g_inst->running) IL_LOGE("poll exit: core requested stop; cleanup runs outside callbacks");
while (__atomic_load_n(&g_do_restart, __ATOMIC_ACQUIRE)) {
IL_LOGI("poll exit: restart requested, destroying old instance");
@@ -442,7 +443,8 @@ static void* instance_thread(void* arg) {
chat_event_post(g_inst, CHAT_EVT_SERVICE_STARTED, NULL, 0);
IL_LOGI("poll exit: restart done, entering new poll loop");
while (!__atomic_load_n(&g_stop, __ATOMIC_ACQUIRE)) uasync_poll(g_ua, -1);
while (!__atomic_load_n(&g_stop, __ATOMIC_ACQUIRE) && g_inst->running) uasync_poll(g_ua, -1);
if (!g_inst->running) IL_LOGE("poll exit: restarted core requested stop; cleanup runs outside callbacks");
}
IL_LOGI("poll exit: final cleanup");
+1 -1
View File
@@ -712,7 +712,7 @@ if(UNIX AND NOT APPLE)
"-Wl,--wrap=call_audio_init" "-Wl,--wrap=call_audio_destroy" "-Wl,--wrap=utun_instance_destroy"
"-Wl,--wrap=uasync_destroy" "-Wl,--wrap=pthread_detach" "-Wl,--wrap=instance_lite_get_instance"
"-Wl,--wrap=utun_bridge_get_local_sockets_json")
foreach(scenario normal restart stream_failure voice_failure)
foreach(scenario normal restart stream_failure voice_failure core_stop restart_core_stop)
add_test(NAME test_android_audio_lifecycle_${scenario} COMMAND test_android_audio_lifecycle ${scenario})
set_tests_properties(test_android_audio_lifecycle_${scenario} PROPERTIES TIMEOUT 20)
endforeach()
@@ -74,7 +74,7 @@ void __real_uasync_destroy(struct UASYNC*, int);
void __wrap_uasync_destroy(struct UASYNC* ua, int flags) {
observe(destroyed && detached >= destroyed, "loop destroyed before core detach/destroy");
__real_uasync_destroy(ua, flags);
pthread_mutex_lock(&observation_lock); ++loops_destroyed; pthread_mutex_unlock(&observation_lock);
pthread_mutex_lock(&observation_lock); ++loops_destroyed; pthread_cond_broadcast(&changed); pthread_mutex_unlock(&observation_lock);
}
int __real_pthread_detach(pthread_t);
@@ -119,11 +119,19 @@ static void inspect(void* arg) {
pthread_mutex_lock(&observation_lock); ++checked; pthread_cond_broadcast(&changed); pthread_mutex_unlock(&observation_lock);
}
static void stop_core(void* arg) {
(void)arg;
struct UTUN_INSTANCE* inst = instance_lite_get_instance();
observe(inst && inst->running && inst->call_audio_ops, "core stop without live voice owner");
utun_instance_stop(inst);
}
int main(int argc, char** argv) {
CHECK_ANDROID(argc == 2);
int restart = !strcmp(argv[1], "restart"), normal = !strcmp(argv[1], "normal");
int core_stop = !strcmp(argv[1], "core_stop") || !strcmp(argv[1], "restart_core_stop");
int restart = !strcmp(argv[1], "restart") || !strcmp(argv[1], "restart_core_stop"), normal = !strcmp(argv[1], "normal");
stream_failure = !strcmp(argv[1], "stream_failure"); voice_failure = !strcmp(argv[1], "voice_failure");
CHECK_ANDROID(restart || normal || stream_failure || voice_failure);
CHECK_ANDROID(restart || normal || core_stop || stream_failure || voice_failure);
ui = pthread_self(); worker = ui;
debug_config_init(); debug_set_level(DEBUG_LEVEL_ERROR); debug_set_category_level(DEBUG_CATEGORY_CALL, DEBUG_LEVEL_INFO);
utun_instance_set_tun_init_enabled(0);
@@ -157,6 +165,10 @@ int main(int argc, char** argv) {
CHECK_ANDROID(wait_for(&checked, 2));
utun_bridge_call_audio_stop();
}
if (core_stop) {
uasync_post(instance_lite_get_uasync(), stop_core, NULL);
CHECK_ANDROID(wait_for(&loops_destroyed, 1u + restart));
}
instance_lite_stop();
CHECK_ANDROID(attached == 1u + restart && detached == attached && destroyed == attached && loops_destroyed == attached);
}