hal: make latch lock recursive
Make latch lock recursive.
Change-Id: I9bc7d5ea6488b2af492d67efeb0fd494c85a7c83
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 83c35c7..baa55e0 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -3426,6 +3426,7 @@
pthread_mutex_lock(&out->latch_lock);
out->offload_state = OFFLOAD_STATE_IDLE;
pthread_mutex_unlock(&out->latch_lock);
+
out->playback_started = 0;
out->send_new_metadata = 1;
if (out->compr != NULL) {
@@ -7749,6 +7750,7 @@
#ifdef AUDIO_GKI_ENABLED
__s32 *generic_dec;
#endif
+ pthread_mutexattr_t latch_attr;
if (is_usb_dev && (!audio_extn_usb_connected(NULL))) {
is_usb_dev = false;
@@ -7778,7 +7780,10 @@
pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
pthread_mutex_init(&out->pre_lock, (const pthread_mutexattr_t *) NULL);
- pthread_mutex_init(&out->latch_lock, (const pthread_mutexattr_t *) NULL);
+ pthread_mutexattr_init(&latch_attr);
+ pthread_mutexattr_settype(&latch_attr, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(&out->latch_lock, &latch_attr);
+ pthread_mutexattr_destroy(&latch_attr);
pthread_mutex_init(&out->position_query_lock, (const pthread_mutexattr_t *) NULL);
pthread_cond_init(&out->cond, (const pthread_condattr_t *) NULL);
@@ -10455,10 +10460,12 @@
if (out->offload_state == OFFLOAD_STATE_PLAYING)
compress_pause(out->compr);
out_set_compr_volume(&out->stream, (float)0, (float)0);
- } else if (out->usecase == USECASE_AUDIO_PLAYBACK_VOIP) {
- out_set_voip_volume(&out->stream, (float)0, (float)0);
} else {
- out_set_pcm_volume(&out->stream, (float)0, (float)0);
+ if (out->usecase == USECASE_AUDIO_PLAYBACK_VOIP)
+ out_set_voip_volume(&out->stream, (float)0, (float)0);
+ else
+ out_set_pcm_volume(&out->stream, (float)0, (float)0);
+
/* wait for stale pcm drained before switching to speaker */
uint32_t latency =
(out->config.period_count * out->config.period_size * 1000) /
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 8caefe8..b357401 100755
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -392,11 +392,12 @@
pthread_mutex_t pre_lock; /* acquire before lock to avoid DOS by playback thread */
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
+ * latch is a supplemetary lock to protect certain fields of out stream (such as
+ * offload_state, a2dp_muted, to add any stream member that needs to be accessed
+ * with device lock held) and it can be held after device lock
*/
pthread_mutex_t latch_lock;
- pthread_mutex_t position_query_lock; /* sychronize frame written */
+ pthread_mutex_t position_query_lock;
struct pcm_config config;
struct compr_config compr_config;
struct pcm *pcm;
@@ -424,7 +425,7 @@
int non_blocking;
int playback_started;
- int offload_state;
+ int offload_state; /* guarded by latch_lock */
pthread_cond_t offload_cond;
pthread_t offload_thread;
struct listnode offload_cmd_list;
@@ -466,7 +467,7 @@
qahwi_stream_out_t qahwi_out;
bool is_iec61937_info_available;
- bool a2dp_muted;
+ bool a2dp_muted; /* guarded by latch_lock */
float volume_l;
float volume_r;
bool apply_volume;
@@ -802,6 +803,7 @@
audio_usecase_t get_usecase_id_from_usecase_type(const struct audio_device *adev,
usecase_type_t type);
+/* adev lock held */
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,
@@ -859,7 +861,8 @@
/*
* NOTE: when multiple mutexes have to be acquired, always take the
- * stream_in or stream_out mutex first, followed by the audio_device mutex.
+ * stream_in or stream_out mutex first, followed by the audio_device mutex
+ * and latch at last.
*/
#endif // QCOM_AUDIO_HW_H