mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
multihandlesink: Use the monotonic clock for detecting timeouts and connection durations
Otherwise real-time clock changes can wrongly trigger timeouts, or not cause timeouts to happen in time. Unfortunately real-time clock times still have to be kept track inside the elements for the statistics. Switching those over to the monotonic clock would cause behaviour changes from the application point of view. The statistics are extended with fields with monotonic times though. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/1137>
This commit is contained in:
parent
26b8a96b84
commit
5a65f5f3b7
4 changed files with 36 additions and 17 deletions
|
@ -671,7 +671,7 @@ gst_multi_fd_sink_handle_client_write (GstMultiFdSink * sink,
|
|||
{
|
||||
gboolean more;
|
||||
gboolean flushing;
|
||||
GstClockTime now;
|
||||
GstClockTime now, now_monotonic;
|
||||
GstMultiHandleSink *mhsink = GST_MULTI_HANDLE_SINK (sink);
|
||||
GstMultiHandleSinkClass *mhsinkclass =
|
||||
GST_MULTI_HANDLE_SINK_GET_CLASS (mhsink);
|
||||
|
@ -685,6 +685,7 @@ gst_multi_fd_sink_handle_client_write (GstMultiFdSink * sink,
|
|||
gint maxsize;
|
||||
|
||||
now = g_get_real_time () * GST_USECOND;
|
||||
now_monotonic = g_get_monotonic_time () * GST_USECOND;
|
||||
|
||||
if (!mhclient->sending) {
|
||||
/* client is not working on a buffer */
|
||||
|
@ -811,6 +812,7 @@ gst_multi_fd_sink_handle_client_write (GstMultiFdSink * sink,
|
|||
/* update stats */
|
||||
mhclient->bytes_sent += wrote;
|
||||
mhclient->last_activity_time = now;
|
||||
mhclient->last_activity_time_monotonic = now_monotonic;
|
||||
mhsink->bytes_served += wrote;
|
||||
}
|
||||
}
|
||||
|
@ -903,7 +905,7 @@ gst_multi_fd_sink_handle_clients (GstMultiFdSink * sink)
|
|||
if (G_UNLIKELY (result == 0)) {
|
||||
GstClockTime now;
|
||||
|
||||
now = g_get_real_time () * GST_USECOND;
|
||||
now = g_get_monotonic_time () * GST_USECOND;
|
||||
|
||||
CLIENTS_LOCK (mhsink);
|
||||
for (clients = mhsink->clients; clients; clients = next) {
|
||||
|
@ -914,7 +916,7 @@ gst_multi_fd_sink_handle_clients (GstMultiFdSink * sink)
|
|||
mhclient = (GstMultiHandleClient *) client;
|
||||
next = g_list_next (clients);
|
||||
if (mhsink->timeout > 0
|
||||
&& now - mhclient->last_activity_time > mhsink->timeout) {
|
||||
&& now - mhclient->last_activity_time_monotonic > mhsink->timeout) {
|
||||
mhclient->status = GST_CLIENT_STATUS_SLOW;
|
||||
gst_multi_handle_sink_remove_client_link (mhsink, clients);
|
||||
}
|
||||
|
|
|
@ -543,9 +543,12 @@ gst_multi_handle_sink_client_init (GstMultiHandleClient * client,
|
|||
|
||||
/* update start time */
|
||||
client->connect_time = g_get_real_time () * GST_USECOND;
|
||||
client->connect_time_monotonic = g_get_monotonic_time () * GST_USECOND;
|
||||
client->disconnect_time = 0;
|
||||
client->disconnect_time_monotonic = 0;
|
||||
/* set last activity time to connect time */
|
||||
client->last_activity_time = client->connect_time;
|
||||
client->last_activity_time_monotonic = client->connect_time_monotonic;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -807,21 +810,28 @@ gst_multi_handle_sink_get_stats (GstMultiHandleSink * sink,
|
|||
|
||||
result = gst_structure_new_empty ("multihandlesink-stats");
|
||||
|
||||
if (mhclient->disconnect_time == 0) {
|
||||
interval = (g_get_real_time () * GST_USECOND) - mhclient->connect_time;
|
||||
if (mhclient->disconnect_time_monotonic == 0) {
|
||||
interval =
|
||||
(g_get_monotonic_time () * GST_USECOND) -
|
||||
mhclient->connect_time_monotonic;
|
||||
} else {
|
||||
interval = mhclient->disconnect_time - mhclient->connect_time;
|
||||
interval =
|
||||
mhclient->disconnect_time_monotonic -
|
||||
mhclient->connect_time_monotonic;
|
||||
}
|
||||
|
||||
gst_structure_set (result,
|
||||
"bytes-sent", G_TYPE_UINT64, mhclient->bytes_sent,
|
||||
"connect-time", G_TYPE_UINT64, mhclient->connect_time,
|
||||
"disconnect-time", G_TYPE_UINT64, mhclient->disconnect_time,
|
||||
"connect-duration", G_TYPE_UINT64, interval,
|
||||
"last-activity-time", G_TYPE_UINT64, mhclient->last_activity_time,
|
||||
"buffers-dropped", G_TYPE_UINT64, mhclient->dropped_buffers,
|
||||
"first-buffer-ts", G_TYPE_UINT64, mhclient->first_buffer_ts,
|
||||
"last-buffer-ts", G_TYPE_UINT64, mhclient->last_buffer_ts, NULL);
|
||||
"connect-time-monotonic", G_TYPE_UINT64,
|
||||
mhclient->connect_time_monotonic, "disconnect-time", G_TYPE_UINT64,
|
||||
mhclient->disconnect_time, "disconnect-time-monotonic", G_TYPE_UINT64,
|
||||
mhclient->disconnect_time_monotonic, "connect-duration", G_TYPE_UINT64,
|
||||
interval, "last-activity-time-monotonic", G_TYPE_UINT64,
|
||||
mhclient->last_activity_time_monotonic, "buffers-dropped",
|
||||
G_TYPE_UINT64, mhclient->dropped_buffers, "first-buffer-ts",
|
||||
G_TYPE_UINT64, mhclient->first_buffer_ts, "last-buffer-ts",
|
||||
G_TYPE_UINT64, mhclient->last_buffer_ts, NULL);
|
||||
}
|
||||
|
||||
noclient:
|
||||
|
@ -891,6 +901,7 @@ gst_multi_handle_sink_remove_client_link (GstMultiHandleSink * sink,
|
|||
mhsinkclass->hash_removing (sink, mhclient);
|
||||
|
||||
mhclient->disconnect_time = g_get_real_time () * GST_USECOND;
|
||||
mhclient->disconnect_time_monotonic = g_get_monotonic_time () * GST_USECOND;
|
||||
|
||||
/* free client buffers */
|
||||
g_slist_foreach (mhclient->sending, (GFunc) gst_mini_object_unref, NULL);
|
||||
|
@ -1652,7 +1663,7 @@ gst_multi_handle_sink_queue_buffer (GstMultiHandleSink * mhsink,
|
|||
}
|
||||
|
||||
max_buffer_usage = 0;
|
||||
now = g_get_real_time () * GST_USECOND;
|
||||
now = g_get_monotonic_time () * GST_USECOND;
|
||||
|
||||
/* now check for new or slow clients */
|
||||
restart:
|
||||
|
@ -1670,7 +1681,8 @@ restart:
|
|||
/* check hard max and timeout, remove client */
|
||||
if ((max_buffers > 0 && mhclient->bufpos >= max_buffers) ||
|
||||
(mhsink->timeout > 0
|
||||
&& now - mhclient->last_activity_time > mhsink->timeout)) {
|
||||
&& now - mhclient->last_activity_time_monotonic >
|
||||
mhsink->timeout)) {
|
||||
/* remove client */
|
||||
GST_WARNING_OBJECT (sink, "%s client %p is too slow, removing",
|
||||
mhclient->debug, mhclient);
|
||||
|
|
|
@ -163,8 +163,11 @@ typedef struct {
|
|||
/* stats */
|
||||
guint64 bytes_sent;
|
||||
guint64 connect_time;
|
||||
guint64 connect_time_monotonic;
|
||||
guint64 disconnect_time;
|
||||
guint64 disconnect_time_monotonic;
|
||||
guint64 last_activity_time;
|
||||
guint64 last_activity_time_monotonic;
|
||||
guint64 dropped_buffers;
|
||||
guint64 avg_queue_size;
|
||||
guint64 first_buffer_ts;
|
||||
|
|
|
@ -825,7 +825,7 @@ gst_multi_socket_sink_handle_client_write (GstMultiSocketSink * sink,
|
|||
{
|
||||
gboolean more;
|
||||
gboolean flushing;
|
||||
GstClockTime now;
|
||||
GstClockTime now, now_monotonic;
|
||||
GError *err = NULL;
|
||||
GstMultiHandleSink *mhsink = GST_MULTI_HANDLE_SINK (sink);
|
||||
GstMultiHandleClient *mhclient = (GstMultiHandleClient *) client;
|
||||
|
@ -834,6 +834,7 @@ gst_multi_socket_sink_handle_client_write (GstMultiSocketSink * sink,
|
|||
|
||||
|
||||
now = g_get_real_time () * GST_USECOND;
|
||||
now_monotonic = g_get_monotonic_time () * GST_USECOND;
|
||||
|
||||
flushing = mhclient->status == GST_CLIENT_STATUS_FLUSHING;
|
||||
|
||||
|
@ -951,6 +952,7 @@ gst_multi_socket_sink_handle_client_write (GstMultiSocketSink * sink,
|
|||
/* update stats */
|
||||
mhclient->bytes_sent += wrote;
|
||||
mhclient->last_activity_time = now;
|
||||
mhclient->last_activity_time_monotonic = now_monotonic;
|
||||
mhsink->bytes_served += wrote;
|
||||
}
|
||||
}
|
||||
|
@ -1115,7 +1117,7 @@ gst_multi_socket_sink_timeout (GstMultiSocketSink * sink)
|
|||
GList *clients;
|
||||
GstMultiHandleSink *mhsink = GST_MULTI_HANDLE_SINK (sink);
|
||||
|
||||
now = g_get_real_time () * GST_USECOND;
|
||||
now = g_get_monotonic_time () * GST_USECOND;
|
||||
|
||||
CLIENTS_LOCK (mhsink);
|
||||
for (clients = mhsink->clients; clients; clients = clients->next) {
|
||||
|
@ -1125,7 +1127,7 @@ gst_multi_socket_sink_timeout (GstMultiSocketSink * sink)
|
|||
client = clients->data;
|
||||
mhclient = (GstMultiHandleClient *) client;
|
||||
if (mhsink->timeout > 0
|
||||
&& now - mhclient->last_activity_time > mhsink->timeout) {
|
||||
&& now - mhclient->last_activity_time_monotonic > mhsink->timeout) {
|
||||
mhclient->status = GST_CLIENT_STATUS_SLOW;
|
||||
gst_multi_handle_sink_remove_client_link (mhsink, clients);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue