aggregator: Protect the tags with the object lock
authorOlivier Crête <olivier.crete@collabora.com>
Thu, 22 Jan 2015 00:33:18 +0000 (19:33 -0500)
committerTim-Philipp Müller <tim@centricular.com>
Sat, 2 Dec 2017 15:10:26 +0000 (15:10 +0000)
The tags related variables were sometimes protected, sometimes not and
sometimes atomic. Put them all under the object lock.

https://bugzilla.gnome.org/show_bug.cgi?id=742684

libs/gst/base/gstaggregator.c

index f0c7261..102173c 100644 (file)
@@ -231,6 +231,7 @@ struct _GstAggregatorPrivate
 
   GstCaps *srccaps;
 
+  /* protected by object lock */
   GstTagList *tags;
   gboolean tags_changed;
 
@@ -409,6 +410,8 @@ static inline void
 gst_aggregator_push_mandatory_events (GstAggregator * self)
 {
   GstAggregatorPrivate *priv = self->priv;
+  GstEvent *segment = NULL;
+  GstEvent *tags = NULL;
 
   if (self->priv->send_stream_start) {
     gchar s_id[32];
@@ -436,26 +439,28 @@ gst_aggregator_push_mandatory_events (GstAggregator * self)
 
   GST_OBJECT_LOCK (self);
   if (self->priv->send_segment && !self->priv->flush_seeking) {
-    GstEvent *segev = gst_event_new_segment (&self->segment);
+    segment = gst_event_new_segment (&self->segment);
 
     if (!self->priv->seqnum)
-      self->priv->seqnum = gst_event_get_seqnum (segev);
+      self->priv->seqnum = gst_event_get_seqnum (segment);
     else
-      gst_event_set_seqnum (segev, self->priv->seqnum);
+      gst_event_set_seqnum (segment, self->priv->seqnum);
     self->priv->send_segment = FALSE;
-    GST_OBJECT_UNLOCK (self);
 
-    GST_DEBUG_OBJECT (self, "pushing segment %" GST_PTR_FORMAT, segev);
-    gst_pad_push_event (self->srcpad, segev);
-  } else {
-    GST_OBJECT_UNLOCK (self);
+    GST_DEBUG_OBJECT (self, "pushing segment %" GST_PTR_FORMAT, segment);
   }
 
   if (priv->tags && priv->tags_changed) {
-    gst_pad_push_event (self->srcpad,
-        gst_event_new_tag (gst_tag_list_ref (priv->tags)));
+    tags = gst_event_new_tag (gst_tag_list_ref (priv->tags));
     priv->tags_changed = FALSE;
   }
+  GST_OBJECT_UNLOCK (self);
+
+  if (segment)
+    gst_pad_push_event (self->srcpad, segment);
+  if (tags)
+    gst_pad_push_event (self->srcpad, tags);
+
 }
 
 /**
@@ -740,7 +745,7 @@ gst_aggregator_flush (GstAggregator * self)
   GST_OBJECT_LOCK (self);
   priv->send_segment = TRUE;
   priv->flush_seeking = FALSE;
-  g_atomic_int_set (&priv->tags_changed, FALSE);
+  priv->tags_changed = FALSE;
   GST_OBJECT_UNLOCK (self);
   if (klass->flush)
     ret = klass->flush (self);
@@ -951,10 +956,6 @@ gst_aggregator_stop (GstAggregator * agg)
 
   gst_aggregator_iterate_sinkpads (agg, gst_aggregator_stop_pad, NULL);
 
-  if (agg->priv->tags)
-    gst_tag_list_unref (agg->priv->tags);
-  agg->priv->tags = NULL;
-
   klass = GST_AGGREGATOR_GET_CLASS (agg);
 
   if (klass->stop)
@@ -962,6 +963,10 @@ gst_aggregator_stop (GstAggregator * agg)
   else
     result = TRUE;
 
+  if (agg->priv->tags)
+    gst_tag_list_unref (agg->priv->tags);
+  agg->priv->tags = NULL;
+
   return result;
 }