a2dp: fix race condition during a2dp suspend and reconfig
Device lock is released during a2dp suspend and re-config scenario,
which results into race condition.
Introduce a latch lock for the following reasons.
- We don't have to hold the out->lock that is too large granularity,
if we only care about certain fields in stream structure.
latch lock is of small granularity.
- out->lock can only be held after adev->lock, which makes it impossible
to loop through the adev->usecase_list and operate on usecase streams.
latch lock can be held after out->lock and adev->lock.
CRs-Fixed: 2770070
Change-Id: I58584820f924ce4c7e723899cb2595aa3adfd5b3
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 403c2a5..3adba6e 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -364,13 +364,18 @@
stream_callback_t client_callback;
void *client_cookie;
};
+
struct stream_out {
struct audio_stream_out stream;
pthread_mutex_t lock; /* see note below on mutex acquisition order */
pthread_mutex_t pre_lock; /* acquire before lock to avoid DOS by playback thread */
- pthread_mutex_t compr_mute_lock; /* acquire before setting compress volume */
- pthread_mutex_t position_query_lock; /* acquire before updating/getting position of track offload*/
pthread_cond_t cond;
+ /* stream_out->lock is of large granularity, and can only be held before device lock
+ * latch is a supplemetary lock to protect certain fields of out stream and
+ * it can be held after device lock
+ */
+ pthread_mutex_t latch_lock;
+ pthread_mutex_t position_query_lock; /* sychronize frame written */
struct pcm_config config;
struct compr_config compr_config;
struct pcm *pcm;
@@ -780,7 +785,7 @@
audio_usecase_t get_usecase_id_from_usecase_type(const struct audio_device *adev,
usecase_type_t type);
-int check_a2dp_restore(struct audio_device *adev, struct stream_out *out, bool restore);
+int check_a2dp_restore_l(struct audio_device *adev, struct stream_out *out, bool restore);
int adev_open_output_stream(struct audio_hw_device *dev,
audio_io_handle_t handle,