Own queued Android phone state data within the worker lifetime
This commit is contained in:
1 parent
2b55d9225a
commit
067c1cd496
3 files changed
+51
-19
No files matched your search
@@ -1370,26 +1370,8 @@ int utun_bridge_set_active(int active) {
|
||||
return instance_lite_set_active(active);
|
||||
}
|
||||
|
||||
struct phone_state_request { struct UTUN_INSTANCE* inst; int state; unsigned policy; };
|
||||
static void phone_state_execute(void* arg) {
|
||||
struct phone_state_request* req = arg;
|
||||
call_set_phone_state(req->inst, req->state, req->policy); u_free(req);
|
||||
}
|
||||
|
||||
int utun_bridge_set_phone_state(int state, unsigned policy) {
|
||||
struct UTUN_INSTANCE* inst = instance_lite_get_instance();
|
||||
struct UASYNC* ua = instance_lite_get_uasync();
|
||||
if (!inst || !ua || !uasync_is_running(ua) || state < 0 || state > 2 || policy > 31) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_CALL, "phone state JNI unavailable state=%d policy=%u", state, policy); return -1;
|
||||
}
|
||||
struct phone_state_request* req = u_calloc(1, sizeof(*req));
|
||||
struct posted_task* task = u_calloc(1, sizeof(*task));
|
||||
if (!req || !task) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CALL, "phone state JNI allocation failed"); u_free(req); u_free(task); return -1;
|
||||
}
|
||||
req->inst = inst; req->state = state; req->policy = policy;
|
||||
task->callback = phone_state_execute; task->arg = req; uasync_post_reserved(ua, task);
|
||||
return 0;
|
||||
return instance_lite_set_phone_state(state, policy);
|
||||
}
|
||||
|
||||
static void bridge_notify_network_active_trampoline(void* arg) {
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "../jni_bridge/android_jni_bridge.h"
|
||||
#include "standby.h"
|
||||
#include "stream_bridge.h"
|
||||
#include "call/call.h"
|
||||
#include "call/call_video_port.h"
|
||||
#ifdef UTUN_WITH_VOICE
|
||||
#include "call/call_audio.h"
|
||||
@@ -716,6 +717,49 @@ int instance_lite_set_active(int active) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* posted — первое поле: uasync освобождает всё выделение и после callback, и при отмене очереди. */
|
||||
struct phone_state_task {
|
||||
struct posted_task posted;
|
||||
int state;
|
||||
unsigned policy;
|
||||
};
|
||||
|
||||
/* Только worker: request заимствован у исполняемой задачи, instance берём в момент применения. */
|
||||
static void set_phone_state_trampoline(void* arg) {
|
||||
const struct phone_state_task* request = arg;
|
||||
struct UTUN_INSTANCE* inst = __atomic_load_n(&g_inst, __ATOMIC_ACQUIRE);
|
||||
if (!inst || __atomic_load_n(&g_stop, __ATOMIC_ACQUIRE)) {
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_CALL, "Android phone state command cancelled: worker is stopping"); return;
|
||||
}
|
||||
call_set_phone_state(inst, request->state, request->policy);
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_CALL, "Android phone state applied state=%d policy=%u", request->state, request->policy);
|
||||
}
|
||||
|
||||
int instance_lite_set_phone_state(int state, unsigned policy) {
|
||||
if (state < 0 || state > 2 || policy > 31) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CALL, "Android phone state request invalid state=%d policy=%u", state, policy); return -1;
|
||||
}
|
||||
if (g_is_worker) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CALL, "Android phone state request refused: frontend thread required"); return -1;
|
||||
}
|
||||
pthread_mutex_lock(&g_stop_mutex);
|
||||
struct UASYNC* ua = __atomic_load_n(&g_ua, __ATOMIC_ACQUIRE);
|
||||
if (!ua || !__atomic_load_n(&g_running, __ATOMIC_ACQUIRE) || __atomic_load_n(&g_stop, __ATOMIC_ACQUIRE)) {
|
||||
pthread_mutex_unlock(&g_stop_mutex);
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_CALL, "Android phone state request rejected: core is not ready"); return -1;
|
||||
}
|
||||
struct phone_state_task* request = u_malloc(sizeof(*request));
|
||||
if (!request) {
|
||||
pthread_mutex_unlock(&g_stop_mutex);
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CALL, "Android phone state request allocation failed"); return -1;
|
||||
}
|
||||
request->state = state; request->policy = policy;
|
||||
request->posted.callback = set_phone_state_trampoline; request->posted.arg = request;
|
||||
uasync_post_reserved(ua, &request->posted);
|
||||
pthread_mutex_unlock(&g_stop_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ── Лёгкое обновление сокетов (auto_sockets=android) ── */
|
||||
|
||||
static void update_sockets_trampoline(void* arg) {
|
||||
|
||||
@@ -71,6 +71,12 @@ int instance_lite_regenerate_keys(const char* config_text);
|
||||
* При stop ожидающая команда может отмениться. Результат применения/stream hold логируется в потоке ядра. */
|
||||
int instance_lite_set_active(int active);
|
||||
|
||||
/* Frontend: поставить состояние SIM (0 UNKNOWN/1 IDLE/2 BUSY) и маску call_policy (0..31) живому worker.
|
||||
* 0 — данные скопированы в задачу под защитой времени жизни uasync; -1 — неверные аргументы/поток, неготовое ядро или OOM.
|
||||
* Применение асинхронно в текущем ядре; stop/restart может отменить ожидающую команду, освободив её данные.
|
||||
* После SERVICE_STARTED frontend повторно отправляет актуальные state/policy. */
|
||||
int instance_lite_set_phone_state(int state, unsigned policy);
|
||||
|
||||
/* Копирует INI, будит poll-loop и пересоздаёт instance и uasync внутри worker.
|
||||
* До остановки проверяет конфиг и сохраняет отсутствующие ключи; отказ оставляет прежнее ядро.
|
||||
* При инициализации ставит запрос в очередь; при завершившемся worker делает join/start.
|
||||
|
||||
Reference in new issue
Block a user