[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