summaryrefslogtreecommitdiff
path: root/src/pulsecore
diff options
context:
space:
mode:
authorArun Raghavan <arun.raghavan@collabora.co.uk>2011-06-02 19:35:09 +0530
committerArun Raghavan <arun.raghavan@collabora.co.uk>2011-06-19 17:46:35 -0700
commitb161a7e07354963558b144a6043ab7ed7d9ab98c (patch)
treebb167e4c16a45a775706567168bac8e92f724dff /src/pulsecore
parenta13da4e93eac1021278e8195c64d9501d7c2d0ef (diff)
protocol-native: Don't leak formats
This clarifies some ownership issues with the formats idxset on the server side so we don't end up leaking formats on errors.
Diffstat (limited to 'src/pulsecore')
-rw-r--r--src/pulsecore/protocol-native.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index d8df8604..b16793d9 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -1037,6 +1037,9 @@ static playback_stream* playback_stream_new(
pa_bool_t relative_volume,
int *ret) {
+ /* Note: This function takes ownership of the 'formats' param, so we need
+ * to take extra care to not leak it */
+
playback_stream *s, *ssync;
pa_sink_input *sink_input = NULL;
pa_memchunk silence;
@@ -1067,7 +1070,7 @@ static playback_stream* playback_stream_new(
sink = ssync->sink_input->sink;
else if (sink != ssync->sink_input->sink) {
*ret = PA_ERR_INVALID;
- return NULL;
+ goto out;
}
}
@@ -1083,8 +1086,11 @@ static playback_stream* playback_stream_new(
pa_sink_input_new_data_set_sample_spec(&data, ss);
if (pa_channel_map_valid(map))
pa_sink_input_new_data_set_channel_map(&data, map);
- if (formats)
+ if (formats) {
pa_sink_input_new_data_set_formats(&data, formats);
+ /* Ownership transferred to new_data, so we don't free it ourseleves */
+ formats = NULL;
+ }
if (volume) {
pa_sink_input_new_data_set_volume(&data, volume);
data.volume_is_absolute = !relative_volume;
@@ -1102,7 +1108,7 @@ static playback_stream* playback_stream_new(
pa_sink_input_new_data_done(&data);
if (!sink_input)
- return NULL;
+ goto out;
s = pa_msgobject_new(playback_stream);
s->parent.parent.parent.free = playback_stream_free;
@@ -1164,6 +1170,11 @@ static playback_stream* playback_stream_new(
(double) s->configured_sink_latency / PA_USEC_PER_MSEC);
pa_sink_input_put(s->sink_input);
+
+out:
+ if (formats)
+ pa_idxset_free(formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
+
return s;
}
@@ -2071,6 +2082,8 @@ static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, u
muted_set = muted_set || muted;
s = playback_stream_new(c, sink, &ss, &map, formats, &attr, volume_set ? &volume : NULL, muted, muted_set, syncid, &missing, flags, p, adjust_latency, early_requests, relative_volume, &ret);
+ /* We no longer own the formats idxset */
+ formats = NULL;
CHECK_VALIDITY_GOTO(c->pstream, s, tag, ret, finish);