summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHavard Graff <havard@pexip.com>2019-11-29 14:23:49 +0100
committerTim-Philipp Müller <tim@centricular.com>2019-11-29 14:33:32 +0000
commit5d79f4bddce27b92f1a9afa02b40e074a676ac92 (patch)
treea1a85fb625fdbf3d1cac7fbbfe675f1bb8d082ca
parentfe014ec6d9c115092098e4917755394cf7ead921 (diff)
downloadgstreamer-plugins-good-5d79f4bddce27b92f1a9afa02b40e074a676ac92.tar.gz
rtpsession: add locking for clear-pt-map
...or it will segfault from time to time...
-rw-r--r--gst/rtpmanager/gstrtpsession.c2
-rw-r--r--tests/check/elements/rtpsession.c44
2 files changed, 46 insertions, 0 deletions
diff --git a/gst/rtpmanager/gstrtpsession.c b/gst/rtpmanager/gstrtpsession.c
index 1d2e96ec5..04fca3716 100644
--- a/gst/rtpmanager/gstrtpsession.c
+++ b/gst/rtpmanager/gstrtpsession.c
@@ -1319,7 +1319,9 @@ return_true (gpointer key, gpointer value, gpointer user_data)
static void
gst_rtp_session_clear_pt_map (GstRtpSession * rtpsession)
{
+ GST_RTP_SESSION_LOCK (rtpsession);
g_hash_table_foreach_remove (rtpsession->priv->ptmap, return_true, NULL);
+ GST_RTP_SESSION_UNLOCK (rtpsession);
}
/* called when the session manager has an RTP packet or a list of packets
diff --git a/tests/check/elements/rtpsession.c b/tests/check/elements/rtpsession.c
index ab9d36aac..ab2c1a192 100644
--- a/tests/check/elements/rtpsession.c
+++ b/tests/check/elements/rtpsession.c
@@ -92,6 +92,8 @@ typedef struct
GObject *internal_session;
GstTestClock *testclock;
GstCaps *caps;
+
+ gboolean running;
} SessionHarness;
static GstCaps *
@@ -1957,6 +1959,46 @@ GST_START_TEST (test_request_late_nack)
GST_END_TEST;
+static gpointer
+_push_caps_events (gpointer user_data)
+{
+ SessionHarness *h = user_data;
+ gint payload = 0;
+ while (h->running) {
+
+ GstCaps *caps = gst_caps_new_simple ("application/x-rtp",
+ "payload", G_TYPE_INT, payload,
+ NULL);
+ gst_harness_set_src_caps (h->recv_rtp_h, caps);
+ g_thread_yield ();
+ payload++;
+ }
+
+ return NULL;
+}
+
+GST_START_TEST (test_clear_pt_map_stress)
+{
+ SessionHarness *h = session_harness_new ();
+ GThread *thread;
+ guint i;
+
+ h->running = TRUE;
+ thread = g_thread_new (NULL, _push_caps_events, h);
+
+ for (i = 0; i < 1000; i++) {
+ g_signal_emit_by_name (h->session, "clear-pt-map");
+ g_thread_yield ();
+ }
+
+ h->running = FALSE;
+ g_thread_join (thread);
+
+ session_harness_free (h);
+}
+
+GST_END_TEST;
+
static Suite *
rtpsession_suite (void)
{
@@ -1988,6 +2030,8 @@ rtpsession_suite (void)
tcase_add_test (tc_chain, test_on_sending_nacks);
tcase_add_test (tc_chain, test_disable_probation);
tcase_add_test (tc_chain, test_request_late_nack);
+ tcase_add_test (tc_chain, test_clear_pt_map_stress);
+
return s;
}