summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2014-08-06 21:19:29 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-08-06 17:19:40 +0000
commit44b2719dcf3e35fb09fbeb9de1a778c1d228dbc2 (patch)
tree21016d5707c3c458844c6b515ffea096b99963e7
parent4ea9b95684508f25d9aa5d55396fc48bdde3085b (diff)
parent05333d458d1c946a17c127372d3ff82558f38ee6 (diff)
downloadlibhardware-44b2719dcf3e35fb09fbeb9de1a778c1d228dbc2.tar.gz
Merge "usb audio: fix set_parameters read/write concurrency" into lmp-dev
-rw-r--r--modules/usbaudio/audio_hw.c82
1 files changed, 52 insertions, 30 deletions
diff --git a/modules/usbaudio/audio_hw.c b/modules/usbaudio/audio_hw.c
index 3a39fea2..22d5e0ff 100644
--- a/modules/usbaudio/audio_hw.c
+++ b/modules/usbaudio/audio_hw.c
@@ -313,28 +313,38 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
int param_val;
int routing = 0;
int ret_value = 0;
+ int card = -1;
+ int device = -1;
struct str_parms * parms = str_parms_create_str(kvpairs);
pthread_mutex_lock(&out->dev->lock);
pthread_mutex_lock(&out->lock);
- bool recache_device_params = false;
param_val = str_parms_get_str(parms, "card", value, sizeof(value));
- if (param_val >= 0) {
- out->profile->card = atoi(value);
- recache_device_params = true;
- }
+ if (param_val >= 0)
+ card = atoi(value);
param_val = str_parms_get_str(parms, "device", value, sizeof(value));
- if (param_val >= 0) {
- out->profile->device = atoi(value);
- recache_device_params = true;
- }
-
- if (recache_device_params && out->profile->card >= 0 && out->profile->device >= 0) {
- ret_value = profile_read_device_info(out->profile) ? 0 : -EINVAL;
+ if (param_val >= 0)
+ device = atoi(value);
+
+ if ((card >= 0) && (card != out->profile->card) &&
+ (device >= 0) && (device != out->profile->device)) {
+ /* cannot read pcm device info if playback is active */
+ if (!out->standby)
+ ret_value = -ENOSYS;
+ else {
+ int saved_card = out->profile->card;
+ int saved_device = out->profile->device;
+ out->profile->card = card;
+ out->profile->device = device;
+ ret_value = profile_read_device_info(out->profile) ? 0 : -EINVAL;
+ if (ret_value != 0) {
+ out->profile->card = saved_card;
+ out->profile->device = saved_device;
+ }
+ }
}
-
pthread_mutex_unlock(&out->lock);
pthread_mutex_unlock(&out->dev->lock);
str_parms_destroy(parms);
@@ -383,15 +393,16 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, si
pthread_mutex_lock(&out->dev->lock);
pthread_mutex_lock(&out->lock);
- pthread_mutex_unlock(&out->dev->lock);
-
if (out->standby) {
ret = start_output_stream(out);
if (ret != 0) {
+ pthread_mutex_unlock(&out->dev->lock);
goto err;
}
out->standby = false;
}
+ pthread_mutex_unlock(&out->dev->lock);
+
alsa_device_proxy* proxy = &out->proxy;
const void * write_buff = buffer;
@@ -687,29 +698,39 @@ static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
int param_val;
int routing = 0;
int ret_value = 0;
+ int card = -1;
+ int device = -1;
struct str_parms * parms = str_parms_create_str(kvpairs);
pthread_mutex_lock(&in->dev->lock);
pthread_mutex_lock(&in->lock);
- bool recache_device_params = false;
-
/* Card/Device */
param_val = str_parms_get_str(parms, "card", value, sizeof(value));
- if (param_val >= 0) {
- in->profile->card = atoi(value);
- recache_device_params = true;
- }
+ if (param_val >= 0)
+ card = atoi(value);
param_val = str_parms_get_str(parms, "device", value, sizeof(value));
- if (param_val >= 0) {
- in->profile->device = atoi(value);
- recache_device_params = true;
- }
-
- if (recache_device_params && in->profile->card >= 0 && in->profile->device >= 0) {
- ret_value = profile_read_device_info(in->profile) ? 0 : -EINVAL;
+ if (param_val >= 0)
+ device = atoi(value);
+
+ if ((card >= 0) && (card != in->profile->card) &&
+ (device >= 0) && (device != in->profile->device)) {
+ /* cannot read pcm device info if playback is active */
+ if (!in->standby)
+ ret_value = -ENOSYS;
+ else {
+ int saved_card = in->profile->card;
+ int saved_device = in->profile->device;
+ in->profile->card = card;
+ in->profile->device = device;
+ ret_value = profile_read_device_info(in->profile) ? 0 : -EINVAL;
+ if (ret_value != 0) {
+ in->profile->card = saved_card;
+ in->profile->device = saved_device;
+ }
+ }
}
pthread_mutex_unlock(&in->lock);
@@ -770,14 +791,15 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer, size_t byte
pthread_mutex_lock(&in->dev->lock);
pthread_mutex_lock(&in->lock);
- pthread_mutex_unlock(&in->dev->lock);
-
if (in->standby) {
if (start_input_stream(in) != 0) {
+ pthread_mutex_unlock(&in->dev->lock);
goto err;
}
in->standby = false;
}
+ pthread_mutex_unlock(&in->dev->lock);
+
alsa_device_profile * profile = in->profile;