summaryrefslogtreecommitdiff
path: root/backends/pulse
diff options
context:
space:
mode:
authorMichal Ratajsky <[email protected]>2014-10-23 22:02:39 +0200
committerMichal Ratajsky <[email protected]>2014-10-23 22:02:39 +0200
commit09c9b73913574a6862135bbcb9d7c2da1f3eea23 (patch)
treefe92da0a6e69d4b5341063a752ccbc01e40ceab1 /backends/pulse
parentb9e004261b979b885e7348484e302176b30d5b54 (diff)
downloadlibmatemixer-09c9b73913574a6862135bbcb9d7c2da1f3eea23.tar.bz2
libmatemixer-09c9b73913574a6862135bbcb9d7c2da1f3eea23.tar.xz
Fix memory management problems
Diffstat (limited to 'backends/pulse')
-rw-r--r--backends/pulse/pulse-backend.c47
-rw-r--r--backends/pulse/pulse-device-switch.c14
-rw-r--r--backends/pulse/pulse-device.c31
-rw-r--r--backends/pulse/pulse-port-switch.c16
-rw-r--r--backends/pulse/pulse-sink.c67
-rw-r--r--backends/pulse/pulse-sink.h2
-rw-r--r--backends/pulse/pulse-source.c65
-rw-r--r--backends/pulse/pulse-source.h2
8 files changed, 163 insertions, 81 deletions
diff --git a/backends/pulse/pulse-backend.c b/backends/pulse/pulse-backend.c
index 4c0697a..56e218e 100644
--- a/backends/pulse/pulse-backend.c
+++ b/backends/pulse/pulse-backend.c
@@ -462,10 +462,16 @@ pulse_backend_close (MateMixerBackend *backend)
g_clear_object (&pulse->priv->connection);
}
+ free_list_devices (pulse);
+ free_list_streams (pulse);
+ free_list_ext_streams (pulse);
+
g_hash_table_remove_all (pulse->priv->devices);
g_hash_table_remove_all (pulse->priv->sinks);
g_hash_table_remove_all (pulse->priv->sources);
g_hash_table_remove_all (pulse->priv->ext_streams);
+ g_hash_table_remove_all (pulse->priv->sink_inputs);
+ g_hash_table_remove_all (pulse->priv->source_outputs);
pulse->priv->connected_once = FALSE;
@@ -761,7 +767,7 @@ on_connection_card_info (PulseConnection *connection,
g_hash_table_insert (pulse->priv->devices,
GUINT_TO_POINTER (info->index),
- g_object_ref (device));
+ device);
free_list_devices (pulse);
g_signal_emit_by_name (G_OBJECT (pulse),
@@ -810,10 +816,11 @@ on_connection_sink_info (PulseConnection *connection,
if (stream == NULL) {
stream = PULSE_STREAM (pulse_sink_new (connection, info, device));
- free_list_streams (pulse);
g_hash_table_insert (pulse->priv->sinks,
GUINT_TO_POINTER (info->index),
- g_object_ref (stream));
+ stream);
+
+ free_list_streams (pulse);
if (device != NULL) {
pulse_device_add_stream (device, stream);
@@ -847,8 +854,8 @@ on_connection_sink_removed (PulseConnection *connection,
g_object_ref (stream);
- free_list_streams (pulse);
g_hash_table_remove (pulse->priv->sinks, GUINT_TO_POINTER (idx));
+ free_list_streams (pulse);
device = pulse_stream_get_device (stream);
if (device != NULL) {
@@ -887,11 +894,10 @@ on_connection_sink_input_info (PulseConnection *connection,
if G_UNLIKELY (sink == NULL)
return;
- pulse_sink_add_input (sink, info);
-
- g_hash_table_insert (pulse->priv->sink_inputs,
- GUINT_TO_POINTER (info->index),
- g_object_ref (sink));
+ if (pulse_sink_add_input (sink, info) == TRUE)
+ g_hash_table_insert (pulse->priv->sink_inputs,
+ GUINT_TO_POINTER (info->index),
+ g_object_ref (sink));
}
static void
@@ -928,10 +934,11 @@ on_connection_source_info (PulseConnection *connection,
if (stream == NULL) {
stream = PULSE_STREAM (pulse_source_new (connection, info, device));
- free_list_streams (pulse);
g_hash_table_insert (pulse->priv->sources,
GUINT_TO_POINTER (info->index),
- g_object_ref (stream));
+ stream);
+
+ free_list_streams (pulse);
if (device != NULL) {
pulse_device_add_stream (device, stream);
@@ -965,8 +972,8 @@ on_connection_source_removed (PulseConnection *connection,
g_object_ref (stream);
- free_list_streams (pulse);
g_hash_table_remove (pulse->priv->sources, GUINT_TO_POINTER (idx));
+ free_list_streams (pulse);
device = pulse_stream_get_device (stream);
if (device != NULL) {
@@ -1005,11 +1012,10 @@ on_connection_source_output_info (PulseConnection *connection,
if G_UNLIKELY (source == NULL)
return;
- pulse_source_add_output (source, info);
-
- g_hash_table_insert (pulse->priv->source_outputs,
- GUINT_TO_POINTER (info->index),
- g_object_ref (source));
+ if (pulse_source_add_output (source, info) == TRUE)
+ g_hash_table_insert (pulse->priv->source_outputs,
+ GUINT_TO_POINTER (info->index),
+ g_object_ref (source));
}
static void
@@ -1047,10 +1053,11 @@ on_connection_ext_stream_info (PulseConnection *connection,
if (ext == NULL) {
ext = pulse_ext_stream_new (connection, info, parent);
- free_list_ext_streams (pulse);
g_hash_table_insert (pulse->priv->ext_streams,
g_strdup (info->name),
- g_object_ref (ext));
+ ext);
+
+ free_list_ext_streams (pulse);
g_signal_emit_by_name (G_OBJECT (pulse),
"stored-control-added",
@@ -1089,8 +1096,8 @@ on_connection_ext_stream_loaded (PulseConnection *connection, PulseBackend *puls
if (PULSE_GET_HANGING (ext) == FALSE)
continue;
- free_list_ext_streams (pulse);
g_hash_table_iter_remove (&iter);
+ free_list_ext_streams (pulse);
g_signal_emit_by_name (G_OBJECT (pulse),
"stored-control-removed",
diff --git a/backends/pulse/pulse-device-switch.c b/backends/pulse/pulse-device-switch.c
index 7a43d0a..bc2490d 100644
--- a/backends/pulse/pulse-device-switch.c
+++ b/backends/pulse/pulse-device-switch.c
@@ -129,7 +129,11 @@ pulse_device_switch_set_property (GObject *object,
switch (param_id) {
case PROP_DEVICE:
/* Construct-only object */
- swtch->priv->device = g_value_dup_object (value);
+ swtch->priv->device = g_value_get_object (value);
+
+ if (swtch->priv->device != NULL)
+ g_object_add_weak_pointer (G_OBJECT (swtch->priv->device),
+ (gpointer *) &swtch->priv->device);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
@@ -152,8 +156,10 @@ pulse_device_switch_dispose (GObject *object)
swtch = PULSE_DEVICE_SWITCH (object);
- g_clear_object (&swtch->priv->device);
-
+ if (swtch->priv->profiles != NULL) {
+ g_list_free_full (swtch->priv->profiles, g_object_unref);
+ swtch->priv->profiles = NULL;
+ }
G_OBJECT_CLASS (pulse_device_switch_parent_class)->dispose (object);
}
@@ -183,7 +189,7 @@ pulse_device_switch_add_profile (PulseDeviceSwitch *swtch, PulseDeviceProfile *p
g_return_if_fail (PULSE_IS_DEVICE_PROFILE (profile));
swtch->priv->profiles = g_list_insert_sorted (swtch->priv->profiles,
- profile,
+ g_object_ref (profile),
compare_profiles);
}
diff --git a/backends/pulse/pulse-device.c b/backends/pulse/pulse-device.c
index 9f33132..71040cc 100644
--- a/backends/pulse/pulse-device.c
+++ b/backends/pulse/pulse-device.c
@@ -38,9 +38,9 @@ struct _PulseDevicePrivate
GHashTable *ports;
GHashTable *streams;
GList *streams_list;
- GList *switches_list;
PulseConnection *connection;
PulseDeviceSwitch *pswitch;
+ GList *pswitch_list;
};
enum {
@@ -79,7 +79,6 @@ static void pulse_device_load (PulseDevice *device,
const pa_card_info *info);
static void free_list_streams (PulseDevice *device);
-static void free_list_switches (PulseDevice *device);
static void
pulse_device_class_init (PulseDeviceClass *klass)
@@ -201,8 +200,11 @@ pulse_device_dispose (GObject *object)
g_clear_object (&device->priv->pswitch);
free_list_streams (device);
- free_list_switches (device);
+ if (device->priv->pswitch_list != NULL) {
+ g_list_free (device->priv->pswitch_list);
+ device->priv->pswitch_list = NULL;
+ }
G_OBJECT_CLASS (pulse_device_parent_class)->dispose (object);
}
@@ -279,12 +281,12 @@ pulse_device_add_stream (PulseDevice *device, PulseStream *stream)
name = mate_mixer_stream_get_name (MATE_MIXER_STREAM (stream));
- free_list_streams (device);
-
g_hash_table_insert (device->priv->streams,
g_strdup (name),
g_object_ref (stream));
+ free_list_streams (device);
+
g_signal_emit_by_name (G_OBJECT (device),
"stream-added",
name);
@@ -363,7 +365,7 @@ pulse_device_list_switches (MateMixerDevice *mmd)
{
g_return_val_if_fail (PULSE_IS_DEVICE (mmd), NULL);
- return PULSE_DEVICE (mmd)->priv->switches_list;
+ return PULSE_DEVICE (mmd)->priv->pswitch_list;
}
static void
@@ -387,7 +389,7 @@ pulse_device_load (PulseDevice *device, const pa_card_info *info)
g_hash_table_insert (device->priv->ports,
g_strdup (name),
- g_object_ref (port));
+ port);
}
#endif
@@ -397,7 +399,7 @@ pulse_device_load (PulseDevice *device, const pa_card_info *info)
_("Profile"),
device);
- device->priv->switches_list = g_list_prepend (NULL, g_object_ref (device->priv->pswitch));
+ device->priv->pswitch_list = g_list_prepend (NULL, device->priv->pswitch);
}
for (i = 0; i < info->n_profiles; i++) {
@@ -421,6 +423,8 @@ pulse_device_load (PulseDevice *device, const pa_card_info *info)
p_info->priority);
pulse_device_switch_add_profile (device->priv->pswitch, profile);
+
+ g_object_unref (profile);
}
}
@@ -434,14 +438,3 @@ free_list_streams (PulseDevice *device)
device->priv->streams_list = NULL;
}
-
-static void
-free_list_switches (PulseDevice *device)
-{
- if (device->priv->switches_list == NULL)
- return;
-
- g_list_free_full (device->priv->switches_list, g_object_unref);
-
- device->priv->switches_list = NULL;
-}
diff --git a/backends/pulse/pulse-port-switch.c b/backends/pulse/pulse-port-switch.c
index db06a7c..71e0709 100644
--- a/backends/pulse/pulse-port-switch.c
+++ b/backends/pulse/pulse-port-switch.c
@@ -53,6 +53,7 @@ static void pulse_port_switch_set_property (GObject *object,
GParamSpec *pspec);
static void pulse_port_switch_init (PulsePortSwitch *swtch);
+static void pulse_port_switch_dispose (GObject *object);
G_DEFINE_ABSTRACT_TYPE (PulsePortSwitch, pulse_port_switch, MATE_MIXER_TYPE_SWITCH)
@@ -73,6 +74,7 @@ pulse_port_switch_class_init (PulsePortSwitchClass *klass)
MateMixerSwitchClass *switch_class;
object_class = G_OBJECT_CLASS (klass);
+ object_class->dispose = pulse_port_switch_dispose;
object_class->get_property = pulse_port_switch_get_property;
object_class->set_property = pulse_port_switch_set_property;
@@ -147,6 +149,20 @@ pulse_port_switch_init (PulsePortSwitch *swtch)
PulsePortSwitchPrivate);
}
+static void
+pulse_port_switch_dispose (GObject *object)
+{
+ PulsePortSwitch *swtch;
+
+ swtch = PULSE_PORT_SWITCH (object);
+
+ if (swtch->priv->ports != NULL) {
+ g_list_free_full (swtch->priv->ports, g_object_unref);
+ swtch->priv->ports = NULL;
+ }
+ G_OBJECT_CLASS (pulse_port_switch_parent_class)->dispose (object);
+}
+
PulseStream *
pulse_port_switch_get_stream (PulsePortSwitch *swtch)
{
diff --git a/backends/pulse/pulse-sink.c b/backends/pulse/pulse-sink.c
index d71ac47..14be2e8 100644
--- a/backends/pulse/pulse-sink.c
+++ b/backends/pulse/pulse-sink.c
@@ -38,9 +38,9 @@ struct _PulseSinkPrivate
{
guint32 monitor;
GHashTable *inputs;
+ GList *inputs_list;
PulsePortSwitch *pswitch;
- GList *streams_list;
- GList *switches_list;
+ GList *pswitch_list;
PulseSinkControl *control;
};
@@ -54,6 +54,8 @@ G_DEFINE_TYPE (PulseSink, pulse_sink, PULSE_TYPE_STREAM);
static const GList *pulse_sink_list_controls (MateMixerStream *mms);
static const GList *pulse_sink_list_switches (MateMixerStream *mms);
+static void free_list_controls (PulseSink *sink);
+
static void
pulse_sink_class_init (PulseSinkClass *klass)
{
@@ -93,11 +95,17 @@ pulse_sink_dispose (GObject *object)
sink = PULSE_SINK (object);
+ g_hash_table_remove_all (sink->priv->inputs);
+
g_clear_object (&sink->priv->control);
g_clear_object (&sink->priv->pswitch);
- g_hash_table_remove_all (sink->priv->inputs);
+ free_list_controls (sink);
+ if (sink->priv->pswitch_list != NULL) {
+ g_list_free (sink->priv->pswitch_list);
+ sink->priv->pswitch_list = NULL;
+ }
G_OBJECT_CLASS (pulse_sink_parent_class)->dispose (object);
}
@@ -164,6 +172,7 @@ pulse_sink_new (PulseConnection *connection,
if (p == info->active_port)
pulse_port_switch_set_active_port (sink->priv->pswitch, port);
}
+ sink->priv->pswitch_list = g_list_prepend (NULL, sink->priv->pswitch);
g_debug ("Created port list for sink %s", info->name);
}
@@ -175,7 +184,7 @@ pulse_sink_new (PulseConnection *connection,
return sink;
}
-void
+gboolean
pulse_sink_add_input (PulseSink *sink, const pa_sink_input_info *info)
{
PulseSinkInput *input;
@@ -188,32 +197,40 @@ pulse_sink_add_input (PulseSink *sink, const pa_sink_input_info *info)
input = pulse_sink_input_new (sink, info);
g_hash_table_insert (sink->priv->inputs,
GINT_TO_POINTER (info->index),
- g_object_ref (input));
+ input);
+
+ free_list_controls (sink);
name = mate_mixer_stream_control_get_name (MATE_MIXER_STREAM_CONTROL (input));
g_signal_emit_by_name (G_OBJECT (sink),
"control-added",
name);
- } else
- pulse_sink_input_update (input, info);
+ return TRUE;
+ }
+
+ pulse_sink_input_update (input, info);
+ return FALSE;
}
void
pulse_sink_remove_input (PulseSink *sink, guint32 index)
{
PulseSinkInput *input;
- const gchar *name;
+ gchar *name;
input = g_hash_table_lookup (sink->priv->inputs, GINT_TO_POINTER (index));
if G_UNLIKELY (input == NULL)
return;
- name = mate_mixer_stream_control_get_name (MATE_MIXER_STREAM_CONTROL (input));
+ name = g_strdup (mate_mixer_stream_control_get_name (MATE_MIXER_STREAM_CONTROL (input)));
g_hash_table_remove (sink->priv->inputs, GINT_TO_POINTER (index));
+
+ free_list_controls (sink);
g_signal_emit_by_name (G_OBJECT (sink),
"control-removed",
name);
+ g_free (name);
}
void
@@ -244,16 +261,21 @@ pulse_sink_get_index_monitor (PulseSink *sink)
static const GList *
pulse_sink_list_controls (MateMixerStream *mms)
{
- GList *list;
+ PulseSink *sink;
g_return_val_if_fail (PULSE_IS_SINK (mms), NULL);
- // XXX
- list = g_hash_table_get_values (PULSE_SINK (mms)->priv->inputs);
- if (list != NULL)
- g_list_foreach (list, (GFunc) g_object_ref, NULL);
+ sink = PULSE_SINK (mms);
+
+ if (sink->priv->inputs_list == NULL) {
+ sink->priv->inputs_list = g_hash_table_get_values (sink->priv->inputs);
+ if (sink->priv->inputs_list != NULL)
+ g_list_foreach (sink->priv->inputs_list, (GFunc) g_object_ref, NULL);
- return g_list_prepend (list, g_object_ref (PULSE_SINK (mms)->priv->control));
+ sink->priv->inputs_list = g_list_prepend (sink->priv->inputs_list,
+ g_object_ref (sink->priv->control));
+ }
+ return sink->priv->inputs_list;
}
static const GList *
@@ -261,9 +283,16 @@ pulse_sink_list_switches (MateMixerStream *mms)
{
g_return_val_if_fail (PULSE_IS_SINK (mms), NULL);
- // XXX
- if (PULSE_SINK (mms)->priv->pswitch != NULL)
- return g_list_prepend (NULL, PULSE_SINK (mms)->priv->pswitch);
+ return PULSE_SINK (mms)->priv->pswitch_list;
+}
+
+static void
+free_list_controls (PulseSink *sink)
+{
+ if (sink->priv->inputs_list == NULL)
+ return;
+
+ g_list_free_full (sink->priv->inputs_list, g_object_unref);
- return NULL;
+ sink->priv->inputs_list = NULL;
}
diff --git a/backends/pulse/pulse-sink.h b/backends/pulse/pulse-sink.h
index 5eaeaa0..355eaf1 100644
--- a/backends/pulse/pulse-sink.h
+++ b/backends/pulse/pulse-sink.h
@@ -63,7 +63,7 @@ PulseSink *pulse_sink_new (PulseConnection *connection,
const pa_sink_info *info,
PulseDevice *device);
-void pulse_sink_add_input (PulseSink *sink,
+gboolean pulse_sink_add_input (PulseSink *sink,
const pa_sink_input_info *info);
void pulse_sink_remove_input (PulseSink *sink, guint32 index);
diff --git a/backends/pulse/pulse-source.c b/backends/pulse/pulse-source.c
index 39ec9b7..61526f5 100644
--- a/backends/pulse/pulse-source.c
+++ b/backends/pulse/pulse-source.c
@@ -37,7 +37,9 @@
struct _PulseSourcePrivate
{
GHashTable *outputs;
+ GList *outputs_list;
PulsePortSwitch *pswitch;
+ GList *pswitch_list;
PulseSourceControl *control;
};
@@ -51,6 +53,8 @@ G_DEFINE_TYPE (PulseSource, pulse_source, PULSE_TYPE_STREAM);
static const GList *pulse_source_list_controls (MateMixerStream *mms);
static const GList *pulse_source_list_switches (MateMixerStream *mms);
+static void free_list_controls (PulseSource *source);
+
static void
pulse_source_class_init (PulseSourceClass *klass)
{
@@ -88,11 +92,17 @@ pulse_source_dispose (GObject *object)
source = PULSE_SOURCE (object);
+ g_hash_table_remove_all (source->priv->outputs);
+
g_clear_object (&source->priv->control);
g_clear_object (&source->priv->pswitch);
- g_hash_table_remove_all (source->priv->outputs);
+ free_list_controls (source);
+ if (source->priv->pswitch_list != NULL) {
+ g_list_free (source->priv->pswitch_list);
+ source->priv->pswitch_list = NULL;
+ }
G_OBJECT_CLASS (pulse_source_parent_class)->dispose (object);
}
@@ -159,6 +169,7 @@ pulse_source_new (PulseConnection *connection,
if (p == info->active_port)
pulse_port_switch_set_active_port (source->priv->pswitch, port);
}
+ source->priv->pswitch_list = g_list_prepend (NULL, source->priv->pswitch);
g_debug ("Created port list for source %s", info->name);
}
@@ -170,7 +181,7 @@ pulse_source_new (PulseConnection *connection,
return source;
}
-void
+gboolean
pulse_source_add_output (PulseSource *source, const pa_source_output_info *info)
{
PulseSourceOutput *output;
@@ -183,32 +194,40 @@ pulse_source_add_output (PulseSource *source, const pa_source_output_info *info)
output = pulse_source_output_new (source, info);
g_hash_table_insert (source->priv->outputs,
GINT_TO_POINTER (info->index),
- g_object_ref (output));
+ output);
+
+ free_list_controls (source);
name = mate_mixer_stream_control_get_name (MATE_MIXER_STREAM_CONTROL (output));
g_signal_emit_by_name (G_OBJECT (source),
"control-added",
name);
- } else
- pulse_source_output_update (output, info);
+ return TRUE;
+ }
+
+ pulse_source_output_update (output, info);
+ return FALSE;
}
void
pulse_source_remove_output (PulseSource *source, guint32 index)
{
PulseSourceOutput *output;
- const gchar *name;
+ gchar *name;
output = g_hash_table_lookup (source->priv->outputs, GINT_TO_POINTER (index));
if G_UNLIKELY (output == NULL)
return;
- name = mate_mixer_stream_control_get_name (MATE_MIXER_STREAM_CONTROL (output));
+ name = g_strdup (mate_mixer_stream_control_get_name (MATE_MIXER_STREAM_CONTROL (output)));
g_hash_table_remove (source->priv->outputs, GINT_TO_POINTER (index));
+
+ free_list_controls (source);
g_signal_emit_by_name (G_OBJECT (source),
"control-removed",
name);
+ g_free (name);
}
void
@@ -230,16 +249,21 @@ pulse_source_update (PulseSource *source,
static const GList *
pulse_source_list_controls (MateMixerStream *mms)
{
- GList *list;
+ PulseSource *source;
g_return_val_if_fail (PULSE_IS_SOURCE (mms), NULL);
- // XXX
- list = g_hash_table_get_values (PULSE_SOURCE (mms)->priv->outputs);
- if (list != NULL)
- g_list_foreach (list, (GFunc) g_object_ref, NULL);
+ source = PULSE_SOURCE (mms);
+
+ if (source->priv->outputs_list == NULL) {
+ source->priv->outputs_list = g_hash_table_get_values (source->priv->outputs);
+ if (source->priv->outputs_list != NULL)
+ g_list_foreach (source->priv->outputs_list, (GFunc) g_object_ref, NULL);
- return g_list_prepend (list, g_object_ref (PULSE_SOURCE (mms)->priv->control));
+ source->priv->outputs_list = g_list_prepend (source->priv->outputs_list,
+ g_object_ref (source->priv->control));
+ }
+ return source->priv->outputs_list;
}
static const GList *
@@ -247,9 +271,16 @@ pulse_source_list_switches (MateMixerStream *mms)
{
g_return_val_if_fail (PULSE_IS_SOURCE (mms), NULL);
- // XXX
- if (PULSE_SOURCE (mms)->priv->pswitch != NULL)
- return g_list_prepend (NULL, PULSE_SOURCE (mms)->priv->pswitch);
+ return PULSE_SOURCE (mms)->priv->pswitch_list;
+}
+
+static void
+free_list_controls (PulseSource *source)
+{
+ if (source->priv->outputs_list == NULL)
+ return;
+
+ g_list_free_full (source->priv->outputs_list, g_object_unref);
- return NULL;
+ source->priv->outputs_list = NULL;
}
diff --git a/backends/pulse/pulse-source.h b/backends/pulse/pulse-source.h
index fdc3d5e..5f82aae 100644
--- a/backends/pulse/pulse-source.h
+++ b/backends/pulse/pulse-source.h
@@ -63,7 +63,7 @@ PulseSource *pulse_source_new (PulseConnection *connection
const pa_source_info *info,
PulseDevice *device);
-void pulse_source_add_output (PulseSource *source,
+gboolean pulse_source_add_output (PulseSource *source,
const pa_source_output_info *info);
void pulse_source_remove_output (PulseSource *source,