aboutsummaryrefslogtreecommitdiff
path: root/audio
diff options
context:
space:
mode:
authorIan Kent <raven@themaw.net>2009-09-28 23:47:44 +0800
committerJaikumar Ganesh <jaikumar@google.com>2011-05-25 11:51:54 -0700
commit71d71d08545fdc8f923119dea69f4c274ca60b71 (patch)
treef68445188d1f0ac4174db8949bc041a495d1f6b5 /audio
parent3da4d6ad9402b574ee4dc7923f1d27b1fa2302a0 (diff)
downloadbluez-71d71d08545fdc8f923119dea69f4c274ca60b71.tar.gz
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
Diffstat (limited to 'audio')
-rwxr-xr-xaudio/liba2dp.c26
1 files changed, 19 insertions, 7 deletions
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();