From 71d71d08545fdc8f923119dea69f4c274ca60b71 Mon Sep 17 00:00:00 2001 From: Ian Kent Date: Mon, 28 Sep 2009 23:47:44 +0800 Subject: bluez a2dp - fix wait_for_start() synchronization On entry to wait_for_start() it's possible we are in state A2DP_STATE_NONE if a2dp_thread() has not completed bluetooth_init(). Also, we call the pthread_mutex_*() functions more frequently than we really need to. Move the mutex locking outside the loop and let condition wait take care of the locking. Also move the A2DP_STATE_NONE check below the condition wait so we can be sure the state machine has been poked before we test it. Change-Id: I020bea365a623e88cb1a5f7e5fccd8f8aa948518 --- audio/liba2dp.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) (limited to 'audio') diff --git a/audio/liba2dp.c b/audio/liba2dp.c index 98fd8cdf..222b188b 100755 --- a/audio/liba2dp.c +++ b/audio/liba2dp.c @@ -884,12 +884,18 @@ static void set_state(struct bluetooth_data *data, a2dp_state_t state) pthread_cond_signal(&data->client_wait); } -static void set_command(struct bluetooth_data *data, a2dp_command_t command) +static void __set_command(struct bluetooth_data *data, a2dp_command_t command) { VDBG("set_command %d\n", command); - pthread_mutex_lock(&data->mutex); data->command = command; pthread_cond_signal(&data->thread_wait); + return; +} + +static void set_command(struct bluetooth_data *data, a2dp_command_t command) +{ + pthread_mutex_lock(&data->mutex); + __set_command(data, command); pthread_mutex_unlock(&data->mutex); } @@ -910,20 +916,26 @@ static int wait_for_start(struct bluetooth_data *data, int timeout) ts.tv_sec = tv.tv_sec + (timeout / 1000); ts.tv_nsec = (tv.tv_usec + (timeout % 1000) * 1000L ) * 1000L; + pthread_mutex_lock(&data->mutex); while (state != A2DP_STATE_STARTED && !err) { if (state == A2DP_STATE_NONE) set_command(data, A2DP_CMD_INIT); else if (state == A2DP_STATE_INITIALIZED) - set_command(data, A2DP_CMD_CONFIGURE); - else if (state == A2DP_STATE_CONFIGURED) - set_command(data, A2DP_CMD_START); + __set_command(data, A2DP_CMD_CONFIGURE); + else if (state == A2DP_STATE_CONFIGURED) { + __set_command(data, A2DP_CMD_START); + } - pthread_mutex_lock(&data->mutex); while ((err = pthread_cond_timedwait(&data->client_wait, &data->mutex, &ts)) == EINTR) ; state = data->state; - pthread_mutex_unlock(&data->mutex); + + if (state == A2DP_STATE_NONE) { + err = ENODEV; + break; + } } + pthread_mutex_unlock(&data->mutex); #ifdef ENABLE_TIMING end = get_microseconds(); -- cgit v1.2.3