android: utun shutdown diagnostics + non-blocking stop + logreceiver doc
- instance_lite: cleanup moved to uasync thread (self-detach), events on start/stop - udp_log: cancel_timer before uasync_destroy, flush on stop, stopping flag - jni_bridge: fixed UDP stop order (cancel_timer → destroy → flush) - instance_lite: u_report_unfreed_blocks at all shutdown paths - chat_event: CHAT_EVT_SERVICE_STARTED/STOPPED for GUI notifications - AGENTS: logreceiver section
This commit is contained in:
1 parent
064bed06f2
commit
0216b0bf50
6 files changed
+57
-23
No files matched your search
@@ -109,6 +109,24 @@ nc localhost 9999
|
||||
> {"id":2,"cmd":"join","link":"utun://..."}
|
||||
```
|
||||
|
||||
## Логирование через logreceiver (только Android)
|
||||
|
||||
Debug-сообщения с телефона дублируются через UDP на приёмник `tools/logreceiver/`.
|
||||
|
||||
Запуск (всегда через скрипт, до старта utun):
|
||||
```bash
|
||||
tools/logreceiver/logreceiver_restart.sh
|
||||
```
|
||||
Скрипт ротирует логи (история 10 запусков: `.log` → `.log.1` → … → `.log.10`),
|
||||
убивает старый демон и запускает новый на `0.0.0.0:9999`, вывод в `logreceiver_output.log`.
|
||||
При каждом запуске логи фиксируются в истории и начинается свежий лог.
|
||||
|
||||
В конфиге Android:
|
||||
```ini
|
||||
log_udp_ip = <ip хоста>
|
||||
log_udp_port = 9999
|
||||
```
|
||||
|
||||
## Ключевые файлы для доработок
|
||||
|
||||
### C-слой
|
||||
|
||||
@@ -358,6 +358,7 @@ JNIEXPORT void JNICALL Java_com_utun_chat_data_NativeLib_nativeStop(
|
||||
JNIEnv* env, jobject thiz) {
|
||||
(void)env; (void)thiz;
|
||||
utun_bridge_destroy();
|
||||
udp_log_stop();
|
||||
}
|
||||
|
||||
/* ── nativeInit (legacy, just saves callbacks) ── */
|
||||
@@ -441,8 +442,9 @@ JNIEXPORT void JNICALL Java_com_utun_chat_data_NativeLib_nativeSetEventCallback(
|
||||
JNIEXPORT void JNICALL Java_com_utun_chat_data_NativeLib_nativeDestroy(
|
||||
JNIEnv* env, jobject thiz) {
|
||||
(void)thiz;
|
||||
udp_log_stop();
|
||||
udp_log_cancel_timer();
|
||||
utun_bridge_destroy();
|
||||
udp_log_stop();
|
||||
if (g_config_callback) { (*env)->DeleteGlobalRef(env, g_config_callback); g_config_callback = NULL; }
|
||||
if (g_log_callback) { (*env)->DeleteGlobalRef(env, g_log_callback); g_log_callback = NULL; }
|
||||
if (g_event_callback) { (*env)->DeleteGlobalRef(env, g_event_callback); g_event_callback = NULL; }
|
||||
|
||||
@@ -22,11 +22,13 @@
|
||||
static int g_udp_fd = -1;
|
||||
static struct sockaddr_in g_udp_addr;
|
||||
static int g_udp_has_addr = 0;
|
||||
static int g_udp_stopping = 0;
|
||||
static char g_udp_buf[UDP_BUF_SIZE];
|
||||
static int g_udp_buf_len = 0;
|
||||
static void* g_udp_timer = NULL;
|
||||
|
||||
static void udp_reschedule_timer(void) {
|
||||
if (g_udp_stopping) return;
|
||||
struct UASYNC* ua = instance_lite_get_uasync();
|
||||
if (ua) g_udp_timer = uasync_set_timeout(ua, UDP_FLUSH_TB, NULL, udp_trampoline, "udp_log_flush");
|
||||
}
|
||||
@@ -63,6 +65,7 @@ void udp_trampoline(void* arg) {
|
||||
|
||||
void udp_log_set_target(const char* ip, int port) {
|
||||
g_udp_buf_len = 0;
|
||||
g_udp_stopping = 0;
|
||||
if (ip && port > 0) {
|
||||
memset(&g_udp_addr, 0, sizeof(g_udp_addr));
|
||||
g_udp_addr.sin_family = AF_INET;
|
||||
@@ -90,11 +93,16 @@ void udp_log_write(const char* data, int len) {
|
||||
}
|
||||
}
|
||||
|
||||
void udp_log_stop(void) {
|
||||
void udp_log_cancel_timer(void) {
|
||||
g_udp_stopping = 1;
|
||||
struct UASYNC* ua = instance_lite_get_uasync();
|
||||
if (ua && g_udp_timer) uasync_cancel_timeout(ua, g_udp_timer);
|
||||
g_udp_timer = NULL;
|
||||
}
|
||||
|
||||
void udp_log_stop(void) {
|
||||
g_udp_stopping = 1;
|
||||
if (g_udp_buf_len > 0) { udp_do_send(g_udp_buf, g_udp_buf_len); g_udp_buf_len = 0; }
|
||||
if (g_udp_fd >= 0) { close(g_udp_fd); g_udp_fd = -1; }
|
||||
g_udp_has_addr = 0;
|
||||
g_udp_buf_len = 0;
|
||||
}
|
||||
@@ -19,7 +19,10 @@ void udp_log_set_target(const char* ip, int port);
|
||||
* Thread-safe — call from any thread (bridge_debug_hook). */
|
||||
void udp_log_write(const char* data, int len);
|
||||
|
||||
/* Stop sending, close socket, cancel timer. Call from any thread. */
|
||||
/* Cancel flush timer (call before uasync_destroy, while ua is alive). */
|
||||
void udp_log_cancel_timer(void);
|
||||
|
||||
/* Flush buffer, close socket. Call after instance shutdown. */
|
||||
void udp_log_stop(void);
|
||||
|
||||
void udp_trampoline(void* arg);
|
||||
|
||||
@@ -175,6 +175,7 @@ static void* instance_thread(void* arg) {
|
||||
IL_LOGE("utun_instance_create_from_config failed");
|
||||
uasync_destroy(g_ua, 0);
|
||||
g_ua = NULL;
|
||||
u_report_unfreed_blocks();
|
||||
g_running = 0;
|
||||
return NULL;
|
||||
}
|
||||
@@ -207,6 +208,7 @@ static void* instance_thread(void* arg) {
|
||||
g_inst = NULL;
|
||||
uasync_destroy(g_ua, 0);
|
||||
g_ua = NULL;
|
||||
u_report_unfreed_blocks();
|
||||
g_running = 0;
|
||||
return NULL;
|
||||
}
|
||||
@@ -223,12 +225,28 @@ static void* instance_thread(void* arg) {
|
||||
}
|
||||
|
||||
g_running = 1;
|
||||
chat_event_post(CHAT_EVT_SERVICE_STARTED, NULL, 0);
|
||||
|
||||
while (!g_stop) {
|
||||
uasync_poll(g_ua, 100);
|
||||
}
|
||||
|
||||
IL_LOGI("poll loop exit");
|
||||
IL_LOGI("poll loop exit, cleaning up");
|
||||
|
||||
if (g_inst) {
|
||||
utun_instance_destroy(g_inst);
|
||||
g_inst = NULL;
|
||||
}
|
||||
if (g_ua) {
|
||||
uasync_destroy(g_ua, 0);
|
||||
g_ua = NULL;
|
||||
}
|
||||
u_report_unfreed_blocks();
|
||||
g_running = 0;
|
||||
chat_event_post(CHAT_EVT_SERVICE_STOPPED, NULL, 0);
|
||||
g_event_handler = NULL;
|
||||
pthread_detach(pthread_self());
|
||||
IL_LOGI("cleanup complete");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -272,27 +290,10 @@ int instance_lite_start(const char* config_text) {
|
||||
}
|
||||
|
||||
void instance_lite_stop(void) {
|
||||
if (!g_running && !g_inst) return;
|
||||
if (!g_inst && !g_running) return;
|
||||
IL_LOGI("stopping...");
|
||||
|
||||
g_stop = 1;
|
||||
if (g_ua) uasync_wakeup(g_ua);
|
||||
pthread_join(g_thread, NULL);
|
||||
|
||||
if (g_inst) {
|
||||
etcp_router_bind(g_inst, ETCP_RT_ID_CHAT_SYNC, NULL);
|
||||
chat_sync_destroy(g_inst);
|
||||
chat_core_destroy(g_inst);
|
||||
utun_instance_destroy(g_inst);
|
||||
g_inst = NULL;
|
||||
}
|
||||
if (g_ua) {
|
||||
uasync_destroy(g_ua, 0);
|
||||
g_ua = NULL;
|
||||
}
|
||||
g_running = 0;
|
||||
g_event_handler = NULL;
|
||||
IL_LOGI("stopped");
|
||||
}
|
||||
|
||||
int instance_lite_is_running(void) {
|
||||
|
||||
Reference in new issue
Block a user