|
|
|
|
@ -157,6 +157,12 @@ static void session_close(struct stream_session *s, int reason, int update_profi
|
|
|
|
|
if (update_profile && group && service_publish_options(s->service, group) != STREAM_OK) |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_STREAM, "stream closed with stale own member options group=%llx", |
|
|
|
|
(unsigned long long)s->descriptor.group_id); |
|
|
|
|
if (!s->service->stopping) { |
|
|
|
|
s->holds++; |
|
|
|
|
if (utun_set_client_activity(s->service->inst, s->service->inst->client_activity_requested) < 0) |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_STREAM, "stream close failed to restore requested core activity"); |
|
|
|
|
s->holds--; |
|
|
|
|
} |
|
|
|
|
if (notify && s->service->callback && !s->service->stopping) session_schedule(s); |
|
|
|
|
else if (!s->holds) session_free(s); |
|
|
|
|
} |
|
|
|
|
@ -322,6 +328,7 @@ int stream_service_init(struct UTUN_INSTANCE *inst) {
|
|
|
|
|
void stream_service_destroy(struct UTUN_INSTANCE *inst) { |
|
|
|
|
struct stream_service *service = inst ? inst->stream : NULL; |
|
|
|
|
if (!service) return; |
|
|
|
|
if (service->stopping) return; |
|
|
|
|
if (service->dispatching || service->initializing) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "stream service destroy inside callback/init rejected"); return; |
|
|
|
|
} |
|
|
|
|
@ -342,6 +349,8 @@ void stream_service_destroy(struct UTUN_INSTANCE *inst) {
|
|
|
|
|
else session_free(s); |
|
|
|
|
} |
|
|
|
|
for (struct STREAM_HANDLE *h = service->handles; h; h = h->next) { h->service = NULL; h->session = NULL; h->reason = STREAM_CLOSE_SERVICE; } |
|
|
|
|
if (utun_set_client_activity(inst, inst->client_activity_requested) < 0) |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_STREAM, "stream stop failed to restore requested core activity"); |
|
|
|
|
inst->stream = NULL; |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_STREAM, "stream service stopped node=%llx", (unsigned long long)inst->node_id); |
|
|
|
|
u_free(service); |
|
|
|
|
@ -401,6 +410,9 @@ static int session_open(struct UTUN_INSTANCE *inst, const struct stream_descript
|
|
|
|
|
h->next = service->handles; service->handles = h; s->owners++; |
|
|
|
|
s->holds++; |
|
|
|
|
int result = created ? service_publish_options(service, stream_group(inst, d->group_id)) : STREAM_OK; |
|
|
|
|
if (result == STREAM_OK && created && utun_set_client_activity(inst, inst->client_activity_requested) < 0) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "stream open failed to activate core"); result = STREAM_ERR_STATE; |
|
|
|
|
} |
|
|
|
|
if (s->closing && result == STREAM_OK) { |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_STREAM, "stream open cancelled during member callbacks"); result = STREAM_ERR_STATE; |
|
|
|
|
} |
|
|
|
|
@ -603,6 +615,13 @@ int stream_ingest_path(struct UTUN_INSTANCE *inst, const uint8_t *wire, size_t l
|
|
|
|
|
|
|
|
|
|
struct stream_network *stream_network_get(struct UTUN_INSTANCE *inst) { return inst && inst->stream ? inst->stream->network : NULL; } |
|
|
|
|
|
|
|
|
|
int stream_service_needs_activity(const struct UTUN_INSTANCE *inst) { |
|
|
|
|
if (!inst || !inst->stream || inst->stream->stopping) return 0; |
|
|
|
|
for (struct stream_session *s = inst->stream->sessions; s; s = s->next) |
|
|
|
|
if (!s->closing && !s->invalidated && s->owners) return 1; |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Доступ network только к существующей локальной подписке точной эпохи. */ |
|
|
|
|
int stream_local_get(struct UTUN_INSTANCE *inst, const struct stream_descriptor *key, struct stream_local *local) { |
|
|
|
|
if (!key || !local || !inst || !inst->stream || inst->stream->stopping) return STREAM_WAIT; |
|
|
|
|
|