Consume repeated viewer demand when delivering its reply

This commit is contained in:
evgeny committed 2026-10-20 18:45:49 +02:00
1 parent 68fb937063
commit ea5d1fcd45
3 files changed
+45 -5

No files matched your search

+14 -3
View File
@@ -17,6 +17,7 @@ struct viewer {
int opening, stopping, resync, requested, waiting;
int video;
int64_t position, audio_ahead;
uint64_t replies, fulfilled_repeats; /* Выданные ответы и погашенные ими повторные запросы. */
};
struct stream_viewers {
pthread_mutex_t lock;
@@ -66,8 +67,9 @@ static void close_viewer(struct viewer *s, enum stream_viewer_kind kind, int rea
if (s->handle) stream_close(s->handle);
s->handle = NULL; s->opening = s->requested = s->waiting = s->resync = 0;
if (kind) output(s, kind, reason, NULL);
DEBUG_INFO(DEBUG_CATEGORY_STREAM, "viewer released id=%llu group=%llx source=%llx kind=%d reason=%d",
(unsigned long long)s->id, (unsigned long long)s->group, (unsigned long long)s->source, kind, reason);
DEBUG_INFO(DEBUG_CATEGORY_STREAM, "viewer released id=%llu group=%llx source=%llx kind=%d reason=%d replies=%llu repeats=%llu",
(unsigned long long)s->id, (unsigned long long)s->group, (unsigned long long)s->source, kind, reason,
(unsigned long long)s->replies, (unsigned long long)s->fulfilled_repeats);
}
/* Событие будит всех readers этой эпохи, не меняя их независимые позиции и запросы. */
@@ -207,7 +209,16 @@ struct stream_viewer_record *stream_viewer_pull(struct stream_viewers *v, uint64
pthread_mutex_lock(&v->lock);
struct viewer *s = find(v, id);
struct stream_viewer_record *r = s && !s->stopping ? s->record : NULL;
if (r) s->record = NULL;
if (r) {
/* Ответ обслуживает и повторный request: AVAILABLE не должен прочитать следующий кадр до нового demand. */
int repeated = s->requested;
s->record = NULL; s->requested = 0; s->replies++;
if (repeated) s->fulfilled_repeats++;
if (s->replies == 1 || (repeated && (s->fulfilled_repeats == 1 || s->fulfilled_repeats % 256 == 0)))
DEBUG_DEBUG(DEBUG_CATEGORY_STREAM, "viewer reply id=%llu kind=%d pts=%llu repeated=%d replies=%llu repeats=%llu pending=0",
(unsigned long long)s->id, r->kind, (unsigned long long)r->pts, repeated,
(unsigned long long)s->replies, (unsigned long long)s->fulfilled_repeats);
}
pthread_mutex_unlock(&v->lock); return r;
}
+2 -1
View File
@@ -30,7 +30,8 @@ void stream_viewers_destroy(struct stream_viewers *viewers);
* Открытие асинхронно: OPENED/CLOSED возвращается через pull. tracks — VIDEO или VIDEO|AUDIO. */
int stream_viewer_open(struct stream_viewers *viewers, uint64_t id, uint64_t group, uint64_t source, uint64_t epoch, unsigned tracks);
void stream_viewer_stop(struct stream_viewers *viewers, uint64_t id);
/* Один owned ответ или NULL. Новые данные запрашиваются request; idle не копирует кольцо. */
/* Один owned ответ или NULL. Выдача ответа погашает demand, включая повторный request до pull.
* NULL сохраняет ожидающий запрос. Следующие данные требуют нового request; idle не копирует кольцо. */
struct stream_viewer_record *stream_viewer_pull(struct stream_viewers *viewers, uint64_t id);
/* Позиция и audio_ahead относятся только к этому reader; повторный demand заменяет прежний.
* 0 — принято, -1 — неизвестный/закрытый ID или ошибка scheduling. */