ext/alsa/gstalsasink.*: Don't leak allocated snd_output_t structure if there's more...
authorTim-Philipp Müller <tim@centricular.net>
Mon, 15 May 2006 16:46:44 +0000 (16:46 +0000)
committerTim-Philipp Müller <tim@centricular.net>
Mon, 15 May 2006 16:46:44 +0000 (16:46 +0000)
Original commit message from CVS:
* ext/alsa/gstalsasink.c: (gst_alsasink_finalise),
(gst_alsasink_init):
* ext/alsa/gstalsasink.h:
Don't leak allocated snd_output_t structure if there's
more than one alsasink instance at a time (#341873).
Also fix GObject macros in header file.

ChangeLog
ext/alsa/gstalsasink.c
ext/alsa/gstalsasink.h

index 3e222aa..1d73e35 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2006-05-15  Tim-Philipp Müller  <tim at centricular dot net>
 
+       * ext/alsa/gstalsasink.c: (gst_alsasink_finalise),
+       (gst_alsasink_init):
+       * ext/alsa/gstalsasink.h:
+         Don't leak allocated snd_output_t structure if there's
+         more than one alsasink instance at a time (#341873).
+         Also fix GObject macros in header file.
+         
+2006-05-15  Tim-Philipp Müller  <tim at centricular dot net>
+
        * gst/subparse/gstsubparse.c:
        (gst_sub_parse_data_format_autodetect):
          Don't use libxml functions in the typefinding code.
index 3310747..d230686 100644 (file)
@@ -96,6 +96,10 @@ static guint gst_alsasink_write (GstAudioSink * asink, gpointer data,
 static guint gst_alsasink_delay (GstAudioSink * asink);
 static void gst_alsasink_reset (GstAudioSink * asink);
 
+static gint output_ref;         /* 0    */
+static snd_output_t *output;    /* NULL */
+static GStaticMutex output_mutex = G_STATIC_MUTEX_INIT;
+
 /* AlsaSink signals and args */
 enum
 {
@@ -173,6 +177,14 @@ gst_alsasink_finalise (GObject * object)
   g_free (sink->device);
   g_mutex_free (sink->alsa_lock);
 
+  g_static_mutex_lock (&output_mutex);
+  --output_ref;
+  if (output_ref == 0) {
+    snd_output_close (output);
+    output = NULL;
+  }
+  g_static_mutex_unlock (&output_mutex);
+
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
@@ -279,8 +291,6 @@ gst_alsasink_get_property (GObject * object, guint prop_id,
   }
 }
 
-static snd_output_t *output = NULL;
-
 static void
 gst_alsasink_init (GstAlsaSink * alsasink)
 {
@@ -291,7 +301,12 @@ gst_alsasink_init (GstAlsaSink * alsasink)
   alsasink->cached_caps = NULL;
   alsasink->alsa_lock = g_mutex_new ();
 
-  snd_output_stdio_attach (&output, stdout, 0);
+  g_static_mutex_lock (&output_mutex);
+  if (output_ref == 0) {
+    snd_output_stdio_attach (&output, stdout, 0);
+    ++output_ref;
+  }
+  g_static_mutex_unlock (&output_mutex);
 }
 
 #define CHECK(call, error) \
index bd2179f..5cf29d3 100644 (file)
 
 G_BEGIN_DECLS
 
-#define GST_TYPE_ALSA_SINK          (gst_alsasink_get_type())
-#define GST_ALSA_SINK(obj)          (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ALSA_SINK,GstAlsaSink))
-#define GST_ALSA_SINK_CLASS(klass)  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ALSA_SINK,GstAlsaSinkClass))
-#define GST_IS_ALSA_SINK(obj)       (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ALSA_SINK))
-#define GST_IS_ALSA_SINK_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ALSA_SINK))
-#define GST_ALSA_SINK_CAST(obj)     ((GstAlsaSink *) (obj))
+#define GST_TYPE_ALSA_SINK            (gst_alsasink_get_type())
+#define GST_ALSA_SINK(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ALSA_SINK,GstAlsaSink))
+#define GST_ALSA_SINK_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ALSA_SINK,GstAlsaSinkClass))
+#define GST_IS_ALSA_SINK(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ALSA_SINK))
+#define GST_IS_ALSA_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ALSA_SINK))
+#define GST_ALSA_SINK_CAST(obj)       ((GstAlsaSink *) (obj))
 
 typedef struct _GstAlsaSink GstAlsaSink;
 typedef struct _GstAlsaSinkClass GstAlsaSinkClass;