[farsight2/master] msn: Use the conf lock to protect session

Olivier Crête olivier.crete at collabora.co.uk
Tue Jul 14 09:50:50 PDT 2009


---
 gst/fsmsnconference/fs-msn-session.c |  103 ++++++++++++++++++++++++----------
 gst/fsmsnconference/fs-msn-session.h |    7 --
 2 files changed, 73 insertions(+), 37 deletions(-)

diff --git a/gst/fsmsnconference/fs-msn-session.c b/gst/fsmsnconference/fs-msn-session.c
index 37f3343..dd8a08f 100644
--- a/gst/fsmsnconference/fs-msn-session.c
+++ b/gst/fsmsnconference/fs-msn-session.c
@@ -84,7 +84,7 @@ struct _FsMsnSessionPrivate
   guint session_id;
   guint initial_port;
 
-  gboolean disposed;
+  GMutex *mutex; /* protects the conference */
 };
 
 G_DEFINE_TYPE (FsMsnSession, fs_msn_session, FS_TYPE_SESSION);
@@ -190,26 +190,47 @@ fs_msn_session_init (FsMsnSession *self)
 {
   /* member init */
   self->priv = FS_MSN_SESSION_GET_PRIVATE (self);
-  self->priv->disposed = FALSE;
   self->priv->construction_error = NULL;
   self->priv->session_id = g_random_int_range (9000, 9999);
 
-  g_static_mutex_init (&self->mutex);
+  self->priv->mutex = g_mutex_new ();
 
   self->priv->media_type = FS_MEDIA_TYPE_LAST + 1;
 }
 
+
+static FsMsnConference *
+fs_msn_session_get_conference (FsMsnSession *self, GError **error)
+{
+  FsMsnConference *conference;
+
+  g_mutex_lock (self->priv->mutex);
+  conference = self->priv->conference;
+  if (conference)
+    g_object_ref (conference);
+  g_mutex_unlock (self->priv->mutex);
+
+  if (!conference)
+    g_set_error (error, FS_ERROR, FS_ERROR_DISPOSED,
+        "Called function after session has been disposed");
+
+  return conference;
+}
+
+
 static void
 fs_msn_session_dispose (GObject *object)
 {
   FsMsnSession *self = FS_MSN_SESSION (object);
   GstBin *conferencebin = NULL;
+  FsMsnConference *conference = fs_msn_session_get_conference (self, NULL);
+  GstElement *valve = NULL;
 
-  if (self->priv->disposed)
-    /* If dispose did already run, return. */
-    return;
+  g_mutex_lock (self->priv->mutex);
+  self->priv->conference = NULL;
+  g_mutex_unlock (self->priv->mutex);
 
-  conferencebin = GST_BIN (self->priv->conference);
+  conferencebin = GST_BIN (conference);
 
   if (!conferencebin)
     goto out;
@@ -217,28 +238,28 @@ fs_msn_session_dispose (GObject *object)
   if (self->priv->media_sink_pad)
     gst_pad_set_active (self->priv->media_sink_pad, FALSE);
 
-  if (self->priv->valve)
+  GST_OBJECT_LOCK (conference);
+  valve = self->priv->valve;
+  self->priv->valve = NULL;
+  GST_OBJECT_UNLOCK (conference);
+
+  if (valve)
   {
-    gst_element_set_locked_state (self->priv->valve, TRUE);
-    gst_element_set_state (self->priv->valve, GST_STATE_NULL);
-    gst_bin_remove (conferencebin, self->priv->valve);
+    gst_element_set_locked_state (valve, TRUE);
+    gst_element_set_state (valve, GST_STATE_NULL);
+    gst_bin_remove (conferencebin, valve);
   }
-  self->priv->valve = NULL;
 
   if (self->priv->media_sink_pad)
-    gst_element_remove_pad (GST_ELEMENT (self->priv->conference),
+    gst_element_remove_pad (GST_ELEMENT (conference),
         self->priv->media_sink_pad);
   self->priv->media_sink_pad = NULL;
 
-  if (conferencebin)
-    gst_object_unref (conferencebin);
-  self->priv->conference = NULL;
+  gst_object_unref (conferencebin);
+  gst_object_unref (conference);
 
  out:
 
-  /* MAKE sure dispose does not run twice. */
-  self->priv->disposed = TRUE;
-
   parent_class->dispose (object);
 }
 
@@ -247,7 +268,7 @@ fs_msn_session_finalize (GObject *object)
 {
   FsMsnSession *self = FS_MSN_SESSION (object);
 
-  g_static_mutex_free (&self->mutex);
+  g_mutex_free (self->priv->mutex);
 
   parent_class->finalize (object);
 }
@@ -259,6 +280,10 @@ fs_msn_session_get_property (GObject *object,
                              GParamSpec *pspec)
 {
   FsMsnSession *self = FS_MSN_SESSION (object);
+  FsMsnConference *conference = fs_msn_session_get_conference (self, NULL);
+
+  if (!conference)
+    return;
 
   switch (prop_id)
   {
@@ -307,6 +332,8 @@ fs_msn_session_get_property (GObject *object,
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
   }
+
+  gst_object_unref (conference);
 }
 
 static void
@@ -316,6 +343,10 @@ fs_msn_session_set_property (GObject *object,
                              GParamSpec *pspec)
 {
   FsMsnSession *self = FS_MSN_SESSION (object);
+  FsMsnConference *conference = fs_msn_session_get_conference (self, NULL);
+
+  if (!conference)
+    return;
 
   switch (prop_id)
   {
@@ -343,6 +374,8 @@ fs_msn_session_set_property (GObject *object,
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
   }
+
+  gst_object_unref (conference);
 }
 
 static void
@@ -402,11 +435,16 @@ _remove_stream (gpointer user_data,
                 GObject *where_the_object_was)
 {
   FsMsnSession *self = FS_MSN_SESSION (user_data);
+  FsMsnConference *conference = fs_msn_session_get_conference (self, NULL);
+
+  if (!conference)
+    return;
 
-  FS_MSN_SESSION_LOCK (self);
+  GST_OBJECT_LOCK (conference);
   if (self->priv->stream == (FsMsnStream *) where_the_object_was)
     self->priv->stream = NULL;
-  FS_MSN_SESSION_UNLOCK (self);
+  GST_OBJECT_UNLOCK (conference);
+  gst_object_unref (conference);
 }
 
 /**
@@ -435,7 +473,7 @@ fs_msn_session_new_stream (FsSession *session,
   FsMsnSession *self = FS_MSN_SESSION (session);
   FsMsnParticipant *msnparticipant = NULL;
   FsStream *new_stream = NULL;
-
+  FsMsnConference *conference;
 
   if (!FS_IS_MSN_PARTICIPANT (participant))
   {
@@ -444,30 +482,35 @@ fs_msn_session_new_stream (FsSession *session,
     return NULL;
   }
 
-  FS_MSN_SESSION_LOCK (self);
+  conference = fs_msn_session_get_conference (self, error);
+  if (!conference)
+    return FALSE;
+
+  GST_OBJECT_LOCK (conference);
   if (self->priv->stream)
   {
-    FS_MSN_SESSION_UNLOCK (self);
+    GST_OBJECT_UNLOCK (conference);
+    gst_object_unref (conference);
     g_set_error (error, FS_ERROR, FS_ERROR_ALREADY_EXISTS,
         "There already is a stream in this session");
     return NULL;
   }
-  FS_MSN_SESSION_UNLOCK (self);
+  GST_OBJECT_UNLOCK (conference);
 
   msnparticipant = FS_MSN_PARTICIPANT (participant);
 
   new_stream = FS_STREAM_CAST (fs_msn_stream_new (self, msnparticipant,
-          direction, self->priv->conference, self->priv->valve,
+          direction, conference, self->priv->valve,
           self->priv->session_id, self->priv->initial_port, error));
 
   if (new_stream)
   {
-    FS_MSN_SESSION_LOCK (self);
+    GST_OBJECT_LOCK (conference);
     self->priv->stream = (FsMsnStream *) new_stream;
     g_object_weak_ref (G_OBJECT (new_stream), _remove_stream, self);
-    FS_MSN_SESSION_UNLOCK (self);
+    GST_OBJECT_UNLOCK (conference);
   }
-
+  gst_object_unref (conference);
 
   return new_stream;
 }
diff --git a/gst/fsmsnconference/fs-msn-session.h b/gst/fsmsnconference/fs-msn-session.h
index acf4a4c..6ba3152 100644
--- a/gst/fsmsnconference/fs-msn-session.h
+++ b/gst/fsmsnconference/fs-msn-session.h
@@ -68,16 +68,9 @@ struct _FsMsnSession
 
   /*< private >*/
 
-  GStaticMutex mutex; /* Should only be accessed using the macros */
-
   FsMsnSessionPrivate *priv;
 };
 
-#define FS_MSN_SESSION_LOCK(session) \
-  g_static_mutex_lock (&FS_MSN_SESSION (session)->mutex)
-#define FS_MSN_SESSION_UNLOCK(session) \
-  g_static_mutex_unlock (&FS_MSN_SESSION (session)->mutex)
-
 
 GType fs_msn_session_get_type (void);
 
-- 
1.5.6.5




More information about the farsight-commits mailing list