multihandlesink: Update bufpos in a separate pass

If a client gets dropped and the iteration gets restarted, bufpos is
incremented again for all clients that preceded the dropped one, causing
havoc.

Adjust the bufpos for all clients first before trying to drop any.

https://bugzilla.gnome.org/show_bug.cgi?id=774908
This commit is contained in:
Jan Alexander Steffens (heftig) 2016-11-23 14:35:04 +01:00 committed by Sebastian Dröge
parent 6c5381eda6
commit 8b9ebd8f88

View file

@ -1704,26 +1704,14 @@ gst_multi_handle_sink_queue_buffer (GstMultiHandleSink * mhsink,
soft_max_buffers);
/* then loop over the clients and update the positions */
max_buffer_usage = 0;
restart:
cookie = mhsink->clients_cookie;
for (clients = mhsink->clients; clients; clients = next) {
for (clients = mhsink->clients; clients; clients = clients->next) {
GstMultiHandleClient *mhclient = clients->data;
g_get_current_time (&nowtv);
now = GST_TIMEVAL_TO_TIME (nowtv);
if (cookie != mhsink->clients_cookie) {
GST_DEBUG_OBJECT (sink, "Clients cookie outdated, restarting");
goto restart;
}
next = g_list_next (clients);
mhclient->bufpos++;
GST_LOG_OBJECT (sink, "%s client %p at position %d",
mhclient->debug, mhclient, mhclient->bufpos);
/* check soft max if needed, recover client */
if (soft_max_buffers > 0 && mhclient->bufpos >= soft_max_buffers) {
gint newpos;
@ -1740,6 +1728,25 @@ restart:
"%s client %p not recovering position", mhclient->debug, mhclient);
}
}
}
max_buffer_usage = 0;
g_get_current_time (&nowtv);
now = GST_TIMEVAL_TO_TIME (nowtv);
/* now check for new or slow clients */
restart:
cookie = mhsink->clients_cookie;
for (clients = mhsink->clients; clients; clients = next) {
GstMultiHandleClient *mhclient = clients->data;
if (cookie != mhsink->clients_cookie) {
GST_DEBUG_OBJECT (sink, "Clients cookie outdated, restarting");
goto restart;
}
next = g_list_next (clients);
/* check hard max and timeout, remove client */
if ((max_buffers > 0 && mhclient->bufpos >= max_buffers) ||
(mhsink->timeout > 0
@ -1761,6 +1768,7 @@ restart:
mhsinkclass->hash_adding (mhsink, mhclient);
hash_changed = TRUE;
}
/* keep track of maximum buffer usage */
if (mhclient->bufpos > max_buffer_usage) {
max_buffer_usage = mhclient->bufpos;