[farsight2/master] Use proper locking when creating special codecs

Olivier Crête olivier.crete at collabora.co.uk
Tue Dec 23 14:50:23 PST 2008


---
 gst/fsrtpconference/fs-rtp-session.c        |   22 +++++----
 gst/fsrtpconference/fs-rtp-session.h        |    5 ++-
 gst/fsrtpconference/fs-rtp-special-source.c |   67 +++++++++++++++++++--------
 gst/fsrtpconference/fs-rtp-special-source.h |    9 ++--
 4 files changed, 69 insertions(+), 34 deletions(-)

diff --git a/gst/fsrtpconference/fs-rtp-session.c b/gst/fsrtpconference/fs-rtp-session.c
index 561c580..b633107 100644
--- a/gst/fsrtpconference/fs-rtp-session.c
+++ b/gst/fsrtpconference/fs-rtp-session.c
@@ -3354,6 +3354,7 @@ _send_src_pad_blocked_callback (GstPad *pad, gboolean blocked,
           TRUE))
     goto done;
 
+
   FS_RTP_SESSION_LOCK (self);
   /* We have to re-fetch the ca because we lifted the lock */
   ca = fs_rtp_session_select_send_codec_locked (self, &error);
@@ -3365,6 +3366,7 @@ _send_src_pad_blocked_callback (GstPad *pad, gboolean blocked,
     goto done_locked;
   }
 
+  fs_codec_destroy (codec_without_config);
   codec_without_config = codec_copy_without_config (ca->codec);
 
   g_clear_error (&error);
@@ -3376,18 +3378,14 @@ _send_src_pad_blocked_callback (GstPad *pad, gboolean blocked,
         "Could not build a new send codec bin", error->message);
   }
 
-  FS_RTP_SESSION_LOCK (self);
-
-  self->priv->extra_sources = fs_rtp_special_sources_create (
-      self->priv->extra_sources,
-      self->priv->codec_associations, codec_without_config,
+  fs_rtp_special_sources_create (
+      &self->priv->extra_sources,
+      &self->priv->codec_associations,
+      FS_RTP_SESSION_GET_LOCK (self),
+      codec_without_config,
       GST_ELEMENT (self->priv->conference),
       self->priv->rtpmuxer);
 
- done_locked:
-
-  FS_RTP_SESSION_UNLOCK (self);
-
  done:
   g_clear_error (&error);
 
@@ -3399,6 +3397,12 @@ _send_src_pad_blocked_callback (GstPad *pad, gboolean blocked,
   fs_codec_destroy (codec_without_config);
 
   gst_pad_set_blocked_async (pad, FALSE, pad_block_do_nothing, NULL);
+
+  return;
+
+ done_locked:
+  FS_RTP_SESSION_UNLOCK (self);
+  goto done;
 }
 
 /**
diff --git a/gst/fsrtpconference/fs-rtp-session.h b/gst/fsrtpconference/fs-rtp-session.h
index 0ea4c0e..55610aa 100644
--- a/gst/fsrtpconference/fs-rtp-session.h
+++ b/gst/fsrtpconference/fs-rtp-session.h
@@ -93,14 +93,17 @@ struct _FsRtpSession
     FS_RTP_SESSION (session)->count--;                \
     g_mutex_unlock (FS_RTP_SESSION (session)->mutex); \
   } while (0);
+#define FS_RTP_SESSION_GET_LOCK(session) \
+  (FS_RTP_SESSION (session)->mutex)
 #else
 #define FS_RTP_SESSION_LOCK(session) \
   g_mutex_lock ((session)->mutex)
 #define FS_RTP_SESSION_UNLOCK(session) \
   g_mutex_unlock ((session)->mutex)
+#define FS_RTP_SESSION_GET_LOCK(session) \
+  ((session)->mutex)
 #endif
 
-#define FS_RTP_SESSION_GET_LOCK(session) ((session)->mutex)
 
 GType fs_rtp_session_get_type (void);
 
diff --git a/gst/fsrtpconference/fs-rtp-special-source.c b/gst/fsrtpconference/fs-rtp-special-source.c
index 2fee5fe..8e326a9 100644
--- a/gst/fsrtpconference/fs-rtp-special-source.c
+++ b/gst/fsrtpconference/fs-rtp-special-source.c
@@ -100,7 +100,8 @@ static void fs_rtp_special_source_finalize (GObject *object);
 
 static FsRtpSpecialSource *
 fs_rtp_special_source_new (FsRtpSpecialSourceClass *klass,
-    GList *negotiated_codecs,
+    GList **negotiated_codecs,
+    GMutex *mutex,
     FsCodec *selected_codec,
     GstElement *bin,
     GstElement *rtpmuxer);
@@ -457,20 +458,22 @@ fs_rtp_special_sources_remove (
 
 /**
  * fs_rtp_special_sources_create:
- * @current_extra_sources: The #GList returned by previous calls to this function
- * @negotiated_codecs: A #GList of current negotiated #CodecAssociation
+ * @current_extra_sources: A pointer to the #GList returned by previous calls
+ * to this function
+ * @negotiated_codecs: A pointer to the #GList of current negotiated
+ * #CodecAssociation
+ * @mutex: the mutex protecting the last two things
  * @send_codec: The currently selected send codec
  * @bin: The #GstBin to add the stuff to
  * @rtpmuxer: The rtpmux element
  *
  * This function add special sources that don't already exist but are needed
- *
- * Returns: A #GList to be passed to other functions in this class
  */
-GList *
+void
 fs_rtp_special_sources_create (
-    GList *current_extra_sources,
-    GList *negotiated_codecs,
+    GList **extra_sources,
+    GList **negotiated_codecs,
+    GMutex *mutex,
     FsCodec *send_codec,
     GstElement *bin,
     GstElement *rtpmuxer)
@@ -479,6 +482,8 @@ fs_rtp_special_sources_create (
 
   fs_rtp_special_sources_init ();
 
+  g_mutex_lock (mutex);
+
   for (klass_item = g_list_first (classes);
        klass_item;
        klass_item = g_list_next (klass_item))
@@ -488,7 +493,7 @@ fs_rtp_special_sources_create (
     FsRtpSpecialSource *obj = NULL;
 
     /* Check if we already have an object for this type */
-    for (obj_item = g_list_first (current_extra_sources);
+    for (obj_item = g_list_first (*extra_sources);
          obj_item;
          obj_item = g_list_next (obj_item))
     {
@@ -498,26 +503,44 @@ fs_rtp_special_sources_create (
     }
 
     if (!obj_item &&
-        fs_rtp_special_source_class_want_source (klass, negotiated_codecs,
+        fs_rtp_special_source_class_want_source (klass, *negotiated_codecs,
             send_codec))
     {
-      obj = fs_rtp_special_source_new (klass, negotiated_codecs, send_codec,
-          bin, rtpmuxer);
+      g_mutex_unlock (mutex);
+      obj = fs_rtp_special_source_new (klass, negotiated_codecs, mutex,
+          send_codec, bin, rtpmuxer);
       if (!obj)
-        goto error;
-      current_extra_sources = g_list_insert_sorted (current_extra_sources,
-          obj, _source_order_compare_func);
+        return;
+
+      g_mutex_lock (mutex);
+
+      /* Check again if we already have an object for this type */
+      for (obj_item = g_list_first (*extra_sources);
+           obj_item;
+           obj_item = g_list_next (obj_item))
+        if (G_OBJECT_TYPE(obj_item->data) == G_OBJECT_CLASS_TYPE(klass))
+          break;
+      if (obj_item)
+      {
+        g_mutex_unlock (mutex);
+        g_object_unref (obj);
+        g_mutex_lock (mutex);
+      }
+      else
+      {
+        *extra_sources = g_list_insert_sorted (*extra_sources,
+            obj, _source_order_compare_func);
+      }
     }
   }
 
- error:
-
-  return current_extra_sources;
+  g_mutex_unlock (mutex);
 }
 
 static FsRtpSpecialSource *
 fs_rtp_special_source_new (FsRtpSpecialSourceClass *klass,
-    GList *negotiated_codecs,
+    GList **negotiated_codecs,
+    GMutex *mutex,
     FsCodec *selected_codec,
     GstElement *bin,
     GstElement *rtpmuxer)
@@ -536,7 +559,11 @@ fs_rtp_special_source_new (FsRtpSpecialSourceClass *klass,
       NULL);
   g_return_val_if_fail (source, NULL);
 
-  source->priv->src = klass->build (source, negotiated_codecs, selected_codec);
+  g_mutex_lock (mutex);
+
+  source->priv->src = klass->build (source, *negotiated_codecs, selected_codec);
+
+  g_mutex_unlock (mutex);
 
   if (!source->priv->src)
     goto error;
diff --git a/gst/fsrtpconference/fs-rtp-special-source.h b/gst/fsrtpconference/fs-rtp-special-source.h
index 19848aa..22a68ed 100644
--- a/gst/fsrtpconference/fs-rtp-special-source.h
+++ b/gst/fsrtpconference/fs-rtp-special-source.h
@@ -57,7 +57,7 @@ typedef struct _FsRtpSpecialSourcePrivate FsRtpSpecialSourcePrivate;
 /**
  * FsRtpSpecialSourceClass:
  * @build: The method builds the source #GstElement from the list of negotiated
- *   codecs and selected codecs, it returns %NULL on error
+ *  codecs and selected codecs, it returns %NULL on error
  * @want_source: Returns %TRUE if a source of this type should be created
  *  according to the selected codec and the negotiated codecs
  * @add_blueprint: Adds #CodecBlueprint structs to the list if the proper
@@ -117,10 +117,11 @@ fs_rtp_special_sources_remove (
     GstElement *bin,
     GstElement *rtpmuxer);
 
-GList *
+void
 fs_rtp_special_sources_create (
-    GList *current_extra_sources,
-    GList *negotiated_codecs,
+    GList **extra_sources,
+    GList **negotiated_codecs,
+    GMutex *mutex,
     FsCodec *send_codec,
     GstElement *bin,
     GstElement *rtpmuxer);
-- 
1.5.6.5




More information about the farsight-commits mailing list