From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx> This fixes the crash reported on: https://github.com/bluez/bluez/issues/60 --- profiles/audio/a2dp.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c index f1e4fa990..a333276e0 100644 --- a/profiles/audio/a2dp.c +++ b/profiles/audio/a2dp.c @@ -105,6 +105,7 @@ struct a2dp_setup { gboolean start; GSList *cb; GIOChannel *io; + guint id; int ref; }; @@ -207,6 +208,9 @@ static void setup_free(struct a2dp_setup *s) g_io_channel_unref(s->io); } + if (s->id) + g_source_remove(s->id); + queue_destroy(s->eps, NULL); setups = g_slist_remove(setups, s); @@ -1166,6 +1170,8 @@ static gboolean a2dp_reconfigure(gpointer data) struct avdtp_media_codec_capability *rsep_codec; struct avdtp_service_capability *cap; + setup->id = 0; + if (!sep->lsep) { error("no valid local SEP"); posix_err = -EINVAL; @@ -1202,6 +1208,20 @@ failed: return FALSE; } +static bool setup_reconfigure(struct a2dp_setup *setup) +{ + if (!setup->reconfigure || setup->id) + return false; + + DBG("%p", setup); + + setup->id = g_timeout_add(RECONFIGURE_TIMEOUT, a2dp_reconfigure, setup); + + setup->reconfigure = FALSE; + + return true; +} + static struct a2dp_remote_sep *get_remote_sep(struct a2dp_channel *chan, struct avdtp_stream *stream) { @@ -1238,8 +1258,7 @@ static void close_cfm(struct avdtp *session, struct avdtp_local_sep *sep, if (!setup->rsep) setup->rsep = get_remote_sep(setup->chan, stream); - if (setup->reconfigure) - g_timeout_add(RECONFIGURE_TIMEOUT, a2dp_reconfigure, setup); + setup_reconfigure(setup); } static void abort_ind(struct avdtp *session, struct avdtp_local_sep *sep, @@ -1283,10 +1302,8 @@ static void abort_cfm(struct avdtp *session, struct avdtp_local_sep *sep, if (!setup) return; - if (setup->reconfigure) { - g_timeout_add(RECONFIGURE_TIMEOUT, a2dp_reconfigure, setup); + if (setup_reconfigure(setup)) return; - } setup_unref(setup); } -- 2.26.2