Keep accepted commands bound to their instance while restart readiness closes
This commit is contained in:
1 parent
f15ca995b7
commit
da540627fc
3 files changed
+10
-2
No files matched your search
@@ -307,13 +307,15 @@ static int check_worker_requests(const char* directory) {
|
||||
pthread_mutex_lock(&worker_test_mutex);
|
||||
while (!worker_entered) pthread_cond_wait(&worker_test_cond, &worker_test_mutex);
|
||||
pthread_mutex_unlock(&worker_test_mutex);
|
||||
int retained_payload = 0;
|
||||
REQUIRE(!instance_lite_post(worker_payload_run, &retained_payload, NULL, worker_payload_discard));
|
||||
REQUIRE(!instance_lite_restart("[global]\ndb_path=/nonexistent/utun-restart-identity/missing\n"));
|
||||
REQUIRE(!instance_lite_is_running());
|
||||
pthread_mutex_lock(&worker_test_mutex);
|
||||
worker_release = 1; pthread_cond_broadcast(&worker_test_cond);
|
||||
pthread_mutex_unlock(&worker_test_mutex);
|
||||
for (int i = 0; i < 1000 && !instance_lite_is_running(); i++) usleep(10000);
|
||||
REQUIRE(instance_lite_is_running());
|
||||
REQUIRE(instance_lite_is_running() && __atomic_load_n(&retained_payload, __ATOMIC_ACQUIRE) == 1);
|
||||
struct worker_query retained = {0}; REQUIRE(!instance_lite_call(worker_read, &retained) && retained.node == query.node);
|
||||
pthread_mutex_lock(&worker_test_mutex);
|
||||
worker_entered = 0; worker_release = 0;
|
||||
|
||||
@@ -93,6 +93,9 @@ Worker снимает media-привязки, уничтожает instance, с
|
||||
каждые две секунды ожидания пишет предупреждение, поток не отсоединяет. Повторный stop безопасен.
|
||||
Restart пересоздаёт instance и uasync. Возврат restart/updateSockets подтверждает принятие копии INI,
|
||||
ошибка очереди возвращается Kotlin; готовность нового запуска подтверждается SERVICE_STARTED.
|
||||
Принятие restart сразу закрывает ready для новых frontend/media запросов. Ошибка подготовки возвращает
|
||||
ready прежнему instance. Ранее принятые команды могут завершиться в прежнем worker до его снятия;
|
||||
после снятия instance они отменяются, даже если uasync обрабатывает оставшиеся callbacks при teardown.
|
||||
Fatal signal handlers принадлежат платформе: worker не заменяет их обработчиком с небезопасными locks/JNI/backtrace.
|
||||
Общие правила освобождения: `../../../doc/service_lifecycle.md`.
|
||||
|
||||
|
||||
@@ -108,6 +108,7 @@ struct frontend_request {
|
||||
void (*callback)(void*);
|
||||
void (*discard)(void*);
|
||||
void* arg;
|
||||
struct UTUN_INSTANCE* instance; /* Привязка к публикации; pending restart закрывает ready, но ещё не уничтожает instance. */
|
||||
};
|
||||
static struct frontend_request* g_frontend_requests; /* Список под g_stop_mutex. */
|
||||
|
||||
@@ -117,7 +118,8 @@ static void frontend_request_run(void* arg) {
|
||||
struct frontend_request** entry = &g_frontend_requests;
|
||||
while (*entry && *entry != request) entry = &(*entry)->next;
|
||||
if (*entry) *entry = request->next;
|
||||
int cancelled = __atomic_load_n(&g_stop, __ATOMIC_ACQUIRE) || !__atomic_load_n(&g_running, __ATOMIC_ACQUIRE);
|
||||
int cancelled = __atomic_load_n(&g_stop, __ATOMIC_ACQUIRE) ||
|
||||
__atomic_load_n(&g_inst, __ATOMIC_ACQUIRE) != request->instance;
|
||||
pthread_mutex_unlock(&g_stop_mutex);
|
||||
if (!cancelled) request->callback(request->arg);
|
||||
else if (request->discard) request->discard(request->arg);
|
||||
@@ -158,6 +160,7 @@ int instance_lite_post(void (*callback)(void*), void* arg, struct UTUN_INSTANCE*
|
||||
u_free(task); u_free(request); return -1;
|
||||
}
|
||||
if (instance_field) *instance_field = inst;
|
||||
request->instance = inst;
|
||||
request->next = g_frontend_requests; g_frontend_requests = request;
|
||||
uasync_post_reserved(ua, task);
|
||||
pthread_mutex_unlock(&g_stop_mutex);
|
||||
|
||||
Reference in new issue
Block a user