srt: Don't take object lock calling gst_srt_object_get_stats

This function takes the sock lock. This can result in a deadlock when
another thread holding the sock lock is trying to take the object lock.

Thread A (Holds object lock, wants sock lock):

    #2  gst_srt_object_get_stats at gst-plugins-bad/ext/srt/gstsrtobject.c:1753
    #3  gst_srt_object_get_property_helper at gst-plugins-bad/ext/srt/gstsrtobject.c:409
    #4  gst_srt_sink_get_property at gst-plugins-bad/ext/srt/gstsrtsink.c:95
    #5  g_object_get_property from libgobject-2.0.so.0

Thread B (Holds sock lock, wants object lock):

    #2  gst_element_post_message_default at gstreamer/gst/gstelement.c:2069
    #3  gst_element_post_message at gstreamer/gst/gstelement.c:2123
    #4  gst_element_message_full_with_details at gstreamer/gst/gstelement.c:2259
    #5  gst_element_message_full at gstreamer/gst/gstelement.c:2298
    #6  gst_srt_object_send_headers at gst-plugins-bad/ext/srt/gstsrtobject.c:1407
    #7  gst_srt_object_send_headers at gst-plugins-bad/ext/srt/gstsrtobject.c:1444
    #8  gst_srt_object_write_to_callers at gst-plugins-bad/ext/srt/gstsrtobject.c:1444
    #9  gst_srt_object_write at gst-plugins-bad/ext/srt/gstsrtobject.c:1598
    #10 gst_srt_sink_render at gst-plugins-bad/ext/srt/gstsrtsink.c:179

Fixes d2d00e07ac.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1861>
This commit is contained in:
Jan Alexander Steffens (heftig) 2020-12-07 14:54:28 +01:00 committed by GStreamer Merge Bot
parent 0243afcb9d
commit 470e6989d2

View file

@ -362,84 +362,99 @@ gboolean
gst_srt_object_get_property_helper (GstSRTObject * srtobject, gst_srt_object_get_property_helper (GstSRTObject * srtobject,
guint prop_id, GValue * value, GParamSpec * pspec) guint prop_id, GValue * value, GParamSpec * pspec)
{ {
GST_OBJECT_LOCK (srtobject->element);
switch (prop_id) { switch (prop_id) {
case PROP_URI: case PROP_URI:
GST_OBJECT_LOCK (srtobject->element);
g_value_take_string (value, gst_uri_to_string (srtobject->uri)); g_value_take_string (value, gst_uri_to_string (srtobject->uri));
GST_OBJECT_UNLOCK (srtobject->element);
break; break;
case PROP_MODE:{ case PROP_MODE:{
GstSRTConnectionMode v; GstSRTConnectionMode v;
GST_OBJECT_LOCK (srtobject->element);
if (!gst_structure_get_enum (srtobject->parameters, "mode", if (!gst_structure_get_enum (srtobject->parameters, "mode",
GST_TYPE_SRT_CONNECTION_MODE, (gint *) & v)) { GST_TYPE_SRT_CONNECTION_MODE, (gint *) & v)) {
GST_WARNING_OBJECT (srtobject->element, "Failed to get 'mode'"); GST_WARNING_OBJECT (srtobject->element, "Failed to get 'mode'");
v = GST_SRT_CONNECTION_MODE_NONE; v = GST_SRT_CONNECTION_MODE_NONE;
} }
g_value_set_enum (value, v); g_value_set_enum (value, v);
GST_OBJECT_UNLOCK (srtobject->element);
break; break;
} }
case PROP_LOCALADDRESS: case PROP_LOCALADDRESS:
GST_OBJECT_LOCK (srtobject->element);
g_value_set_string (value, g_value_set_string (value,
gst_structure_get_string (srtobject->parameters, "localaddress")); gst_structure_get_string (srtobject->parameters, "localaddress"));
GST_OBJECT_UNLOCK (srtobject->element);
break; break;
case PROP_LOCALPORT:{ case PROP_LOCALPORT:{
guint v; guint v;
GST_OBJECT_LOCK (srtobject->element);
if (!gst_structure_get_uint (srtobject->parameters, "localport", &v)) { if (!gst_structure_get_uint (srtobject->parameters, "localport", &v)) {
GST_WARNING_OBJECT (srtobject->element, "Failed to get 'localport'"); GST_WARNING_OBJECT (srtobject->element, "Failed to get 'localport'");
v = GST_SRT_DEFAULT_PORT; v = GST_SRT_DEFAULT_PORT;
} }
g_value_set_uint (value, v); g_value_set_uint (value, v);
GST_OBJECT_UNLOCK (srtobject->element);
break; break;
} }
case PROP_PBKEYLEN:{ case PROP_PBKEYLEN:{
GstSRTKeyLength v; GstSRTKeyLength v;
GST_OBJECT_LOCK (srtobject->element);
if (!gst_structure_get_enum (srtobject->parameters, "pbkeylen", if (!gst_structure_get_enum (srtobject->parameters, "pbkeylen",
GST_TYPE_SRT_KEY_LENGTH, (gint *) & v)) { GST_TYPE_SRT_KEY_LENGTH, (gint *) & v)) {
GST_WARNING_OBJECT (srtobject->element, "Failed to get 'pbkeylen'"); GST_WARNING_OBJECT (srtobject->element, "Failed to get 'pbkeylen'");
v = GST_SRT_KEY_LENGTH_NO_KEY; v = GST_SRT_KEY_LENGTH_NO_KEY;
} }
g_value_set_enum (value, v); g_value_set_enum (value, v);
GST_OBJECT_UNLOCK (srtobject->element);
break; break;
} }
case PROP_POLL_TIMEOUT:{ case PROP_POLL_TIMEOUT:{
gint v; gint v;
GST_OBJECT_LOCK (srtobject->element);
if (!gst_structure_get_int (srtobject->parameters, "poll-timeout", &v)) { if (!gst_structure_get_int (srtobject->parameters, "poll-timeout", &v)) {
GST_WARNING_OBJECT (srtobject->element, "Failed to get 'poll-timeout'"); GST_WARNING_OBJECT (srtobject->element, "Failed to get 'poll-timeout'");
v = GST_SRT_DEFAULT_POLL_TIMEOUT; v = GST_SRT_DEFAULT_POLL_TIMEOUT;
} }
g_value_set_int (value, v); g_value_set_int (value, v);
GST_OBJECT_UNLOCK (srtobject->element);
break; break;
} }
case PROP_LATENCY:{ case PROP_LATENCY:{
gint v; gint v;
GST_OBJECT_LOCK (srtobject->element);
if (!gst_structure_get_int (srtobject->parameters, "latency", &v)) { if (!gst_structure_get_int (srtobject->parameters, "latency", &v)) {
GST_WARNING_OBJECT (srtobject->element, "Failed to get 'latency'"); GST_WARNING_OBJECT (srtobject->element, "Failed to get 'latency'");
v = GST_SRT_DEFAULT_LATENCY; v = GST_SRT_DEFAULT_LATENCY;
} }
g_value_set_int (value, v); g_value_set_int (value, v);
GST_OBJECT_UNLOCK (srtobject->element);
break; break;
} }
case PROP_STATS: case PROP_STATS:
g_value_take_boxed (value, gst_srt_object_get_stats (srtobject)); g_value_take_boxed (value, gst_srt_object_get_stats (srtobject));
break; break;
case PROP_WAIT_FOR_CONNECTION: case PROP_WAIT_FOR_CONNECTION:
GST_OBJECT_LOCK (srtobject->element);
g_value_set_boolean (value, srtobject->wait_for_connection); g_value_set_boolean (value, srtobject->wait_for_connection);
GST_OBJECT_UNLOCK (srtobject->element);
break; break;
case PROP_STREAMID:{ case PROP_STREAMID:
GST_OBJECT_LOCK (srtobject->element);
g_value_set_string (value, g_value_set_string (value,
gst_structure_get_string (srtobject->parameters, "streamid")); gst_structure_get_string (srtobject->parameters, "streamid"));
GST_OBJECT_UNLOCK (srtobject->element);
break; break;
}
default: default:
goto err; return FALSE;
} }
GST_OBJECT_UNLOCK (srtobject->element);
return TRUE; return TRUE;
err:
GST_OBJECT_UNLOCK (srtobject->element);
return FALSE;
} }
void void