audio: Synchronize calls to mmap streams
Synchronize calls to get_position calls on
mmap streams to prevent race with create_mmap_buffer
on these streams
Bug: 69254484
Test: CtsNativeMediaAAudioTestCases
Change-Id: I0e153d0a230e82d37768ad06d3b2619f1a17812f
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index dba1555..0ea8f14 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -2987,6 +2987,7 @@
uint32_t buffer_size;
ALOGV("%s", __func__);
+ lock_output_stream(out);
pthread_mutex_lock(&adev->lock);
if (info == NULL || min_size_frames == 0) {
@@ -3066,32 +3067,36 @@
}
}
pthread_mutex_unlock(&adev->lock);
+ pthread_mutex_unlock(&out->lock);
return ret;
}
static int out_get_mmap_position(const struct audio_stream_out *stream,
struct audio_mmap_position *position)
{
+ int ret = 0;
struct stream_out *out = (struct stream_out *)stream;
ALOGVV("%s", __func__);
if (position == NULL) {
return -EINVAL;
}
- if (out->usecase != USECASE_AUDIO_PLAYBACK_MMAP) {
- return -ENOSYS;
- }
- if (out->pcm == NULL) {
- return -ENOSYS;
+ lock_output_stream(out);
+ if (out->usecase != USECASE_AUDIO_PLAYBACK_MMAP ||
+ out->pcm == NULL) {
+ ret = -ENOSYS;
+ goto exit;
}
struct timespec ts = { 0, 0 };
- int ret = pcm_mmap_get_hw_ptr(out->pcm, (unsigned int *)&position->position_frames, &ts);
+ ret = pcm_mmap_get_hw_ptr(out->pcm, (unsigned int *)&position->position_frames, &ts);
if (ret < 0) {
ALOGE("%s: %s", __func__, pcm_get_error(out->pcm));
- return ret;
+ goto exit;
}
position->time_nanoseconds = audio_utils_ns_from_timespec(&ts);
- return 0;
+exit:
+ pthread_mutex_unlock(&out->lock);
+ return ret;
}
@@ -3583,6 +3588,7 @@
uint32_t mmap_size;
uint32_t buffer_size;
+ lock_input_stream(in);
pthread_mutex_lock(&adev->lock);
ALOGV("%s in %p", __func__, in);
@@ -3666,31 +3672,35 @@
}
}
pthread_mutex_unlock(&adev->lock);
+ pthread_mutex_unlock(&in->lock);
return ret;
}
static int in_get_mmap_position(const struct audio_stream_in *stream,
struct audio_mmap_position *position)
{
+ int ret = 0;
struct stream_in *in = (struct stream_in *)stream;
ALOGVV("%s", __func__);
if (position == NULL) {
return -EINVAL;
}
- if (in->usecase != USECASE_AUDIO_RECORD_MMAP) {
- return -ENOSYS;
- }
- if (in->pcm == NULL) {
- return -ENOSYS;
+ lock_input_stream(in);
+ if (in->usecase != USECASE_AUDIO_RECORD_MMAP ||
+ in->pcm == NULL) {
+ ret = -ENOSYS;
+ goto exit;
}
struct timespec ts = { 0, 0 };
- int ret = pcm_mmap_get_hw_ptr(in->pcm, (unsigned int *)&position->position_frames, &ts);
+ ret = pcm_mmap_get_hw_ptr(in->pcm, (unsigned int *)&position->position_frames, &ts);
if (ret < 0) {
ALOGE("%s: %s", __func__, pcm_get_error(in->pcm));
- return ret;
+ goto exit;
}
position->time_nanoseconds = audio_utils_ns_from_timespec(&ts);
- return 0;
+exit:
+ pthread_mutex_unlock(&in->lock);
+ return ret;
}