Browse Source

Reject overlapping core ownership of Android stream handles

master
evgeny 1 week ago
parent
commit
1dcf6a79ce
  1. 8
      tools/chatgui-android/libutun_lite/instance_lite.c
  2. 13
      tools/chatgui-android/libutun_lite/stream_bridge.c
  3. 3
      tools/chatgui-android/libutun_lite/stream_bridge.h

8
tools/chatgui-android/libutun_lite/instance_lite.c

@ -298,7 +298,7 @@ static void* instance_thread(void* arg) {
IL_LOGI("instance created, node_id=0x%016llx", (unsigned long long)g_inst->node_id);
/* Core owns SQLite and transport; this frontend starts only the chat service. */
if (utun_core_start(g_inst) != 0 || chat_service_start(g_inst) != 0) {
if (utun_core_start(g_inst) != 0 || chat_service_start(g_inst) != 0 || android_stream_attach(g_inst) < 0) {
IL_LOGE("core/chat start failed");
utun_instance_destroy(g_inst);
g_inst = NULL;
@ -312,7 +312,6 @@ static void* instance_thread(void* arg) {
return NULL;
}
android_stream_attach(g_inst);
/* sockets are now created — sync my addresses to DB */
chat_core_sync_my_addresses(g_inst);
fire_local_sockets_event();
@ -389,8 +388,9 @@ static void* instance_thread(void* arg) {
chat_event_set_handler(g_inst, chat_event_forward);
/* Recreate core and chat independently of UTUN. */
if (utun_core_start(g_inst) != 0 || chat_service_start(g_inst) != 0) { IL_LOGE("poll exit: core/chat start failed"); break; }
android_stream_attach(g_inst);
if (utun_core_start(g_inst) != 0 || chat_service_start(g_inst) != 0 || android_stream_attach(g_inst) < 0) {
IL_LOGE("poll exit: core/chat/stream bridge start failed"); break;
}
chat_core_sync_my_addresses(g_inst);
fire_local_sockets_event();
if (g_inst->config->global.name[0]) chat_core_update_my_name(g_inst, g_inst->config->global.name);

13
tools/chatgui-android/libutun_lite/stream_bridge.c

@ -303,11 +303,16 @@ static void media_process(void *arg) {
}
/* Attach/detach — обязательная граница lifetime ядра. */
void android_stream_attach(struct UTUN_INSTANCE *inst) {
int android_stream_attach(struct UTUN_INSTANCE *inst) {
pthread_mutex_lock(&media_lock);
if (!inst || !inst->stream || (media_inst && media_inst != inst)) {
DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "Android stream attach rejected inst=%p owner=%p", (void *)inst, (void *)media_inst);
pthread_mutex_unlock(&media_lock); return -1;
}
media_inst = inst; stream_set_event_callback(inst, media_event, NULL);
DEBUG_INFO(DEBUG_CATEGORY_STREAM, "Android stream bridge attached");
pthread_mutex_unlock(&media_lock);
return 0;
}
void android_stream_detach(struct UTUN_INSTANCE *inst) {
pthread_mutex_lock(&media_lock);
@ -352,7 +357,11 @@ int android_stream_feed(uint64_t id, int video, uint64_t pts, int key, const uin
}
pthread_mutex_lock(&media_lock);
int result = -1, track = video ? 0 : 1;
if (!media_inst || publisher.id != id || publisher.stopping || publisher.finished) goto done;
if (!media_inst || publisher.id != id || publisher.stopping || publisher.finished) {
DEBUG_WARN(DEBUG_CATEGORY_STREAM, "Android stream feed rejected id=%llu owner=%llu attached=%d stopping=%d finished=%d",
(unsigned long long)id, (unsigned long long)publisher.id, media_inst != NULL, publisher.stopping, publisher.finished);
goto done;
}
if ((!video && !publisher.format.audio_codec) || (publisher.seen[track] && pts <= publisher.last_pts[track])) {
DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "Android stream feed invalid track/PTS id=%llu pts=%llu",
(unsigned long long)id, (unsigned long long)pts); goto done;

3
tools/chatgui-android/libutun_lite/stream_bridge.h

@ -12,7 +12,8 @@
#include <stdint.h>
struct UTUN_INSTANCE;
void android_stream_attach(struct UTUN_INSTANCE *inst);
/* 0 attached, -1 invalid/busy: нельзя передать singleton другому ядру до detach старого. */
int android_stream_attach(struct UTUN_INSTANCE *inst);
void android_stream_detach(struct UTUN_INSTANCE *inst);
int android_stream_open(uint64_t id, uint64_t group, uint64_t source, unsigned width, unsigned height,
unsigned rotation, int audio);

Loading…
Cancel
Save