From 906db3cb51f2e89e7f9b1276850c7d1b6662088b Mon Sep 17 00:00:00 2001 From: Weiyin Jiang Date: Tue, 2 Mar 2021 13:17:04 +0800 Subject: [PATCH] hal: make latch lock recursive Make latch lock recursive. Change-Id: I9bc7d5ea6488b2af492d67efeb0fd494c85a7c83 --- hal/audio_hw.c | 15 +++++++++++---- hal/audio_hw.h | 15 +++++++++------ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/hal/audio_hw.c b/hal/audio_hw.c index 83c35c76..baa55e0e 100644 --- a/hal/audio_hw.c +++ b/hal/audio_hw.c @@ -3426,6 +3426,7 @@ static void stop_compressed_output_l(struct stream_out *out) 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 @@ int adev_open_output_stream(struct audio_hw_device *dev, #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 @@ int adev_open_output_stream(struct audio_hw_device *dev, 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 @@ int check_a2dp_restore_l(struct audio_device *adev, struct stream_out *out, bool 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 8caefe8e..b3574018 100755 --- a/hal/audio_hw.h +++ b/hal/audio_hw.h @@ -392,11 +392,12 @@ struct stream_out { 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 @@ struct stream_out { 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 @@ struct stream_out { 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 @@ int pcm_ioctl(struct pcm *pcm, int request, ...); 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 @@ audio_patch_handle_t generate_patch_handle(); /* * 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