From: Mikel Astiz <mikel.astiz@xxxxxxxxxxxx> BlueZ now supports a flag in the accesstype in order to avoid the race condition between the state-test (state should be "Playing") and the call to Acquire(). This fixes the previously existing race condition during profile change. --- src/modules/bluetooth/module-bluetooth-device.c | 15 +++++++-------- 1 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index 68e9cdb..2ebf40e 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -345,7 +345,6 @@ static void teardown_stream(struct userdata *u) { } static void bt_transport_release(struct userdata *u) { - const char *accesstype = "rw"; const pa_bluetooth_transport *t; /* Ignore if already released */ @@ -356,7 +355,7 @@ static void bt_transport_release(struct userdata *u) { t = pa_bluetooth_discovery_get_transport(u->discovery, u->transport); if (t) - pa_bluetooth_transport_release(t, accesstype); + pa_bluetooth_transport_release(t, u->accesstype); pa_xfree(u->accesstype); u->accesstype = NULL; @@ -382,7 +381,7 @@ static pa_bt_audio_state_t get_profile_audio_state(const struct userdata *u, con } static int bt_transport_acquire(struct userdata *u, pa_bool_t start) { - const char *accesstype = "rw"; + const char *accesstype = start ? "rw" : "rw?"; const pa_bluetooth_device *d; const pa_bluetooth_transport *t; @@ -414,13 +413,13 @@ static int bt_transport_acquire(struct userdata *u, pa_bool_t start) { } if (!start) { - /* FIXME: we are trying to acquire the transport only if the stream is + /* We are trying to acquire the transport only if the stream is playing, without actually initiating the stream request from our side (which is typically undesireable specially for hfgw use-cases. - However this approach is racy, since the stream could have been - suspended in the meantime, so we can't really guarantee that the - stream will not be requested until BlueZ's API supports this - atomically. */ + However this approach is racy unless at least BlueZ version 4.xxx is + being used, where the "?" accesstype is supported. The reason is that + the stream could have been suspended just before our call to + Acquire() */ if (get_profile_audio_state(u, d) < PA_BT_AUDIO_STATE_PLAYING) { pa_log_info("Failed optional acquire of transport %s", u->transport); return -1; -- 1.7.7.6