diff options
author | Arun Raghavan <arun.raghavan@collabora.co.uk> | 2011-06-02 19:35:09 +0530 |
---|---|---|
committer | Arun Raghavan <arun.raghavan@collabora.co.uk> | 2011-06-19 17:46:35 -0700 |
commit | b161a7e07354963558b144a6043ab7ed7d9ab98c (patch) | |
tree | bb167e4c16a45a775706567168bac8e92f724dff /src/pulsecore | |
parent | a13da4e93eac1021278e8195c64d9501d7c2d0ef (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.c | 19 |
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); |