diff options
author | Gautam Manam <gmanam@codeaurora.org> | 2020-12-24 14:08:04 +0530 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2020-12-29 22:01:37 -0800 |
commit | feeb11639df4160701777a5abc05be345e74d1eb (patch) | |
tree | 16407da7d08a7cb0db3b91847da1a164766ba9f6 | |
parent | d4e8ced33fbadf778459b4eb36d31343f3068a2f (diff) |
hal: deadlock with pause and SSR for compressed offload
For compress offload playback, during SSR offline
callback will hold out and latch lock and set
offload state to idle and wait on compress
offload thread state to be marked as unblocked.
In the mean time pause is triggered and it acquires
out lock and waits for out_latch lock.
And in another thread compress_wait completes and
wait for out lock causing dead lock.
Fix this by moving latch lock to protect only
offload_state, so that latch lock can be released.
Change-Id: Iec42eaf6c18477b4f87bb5bafe54fb346c7af73b
-rw-r--r-- | hal/audio_hw.c | 15 |
1 files changed, 5 insertions, 10 deletions
diff --git a/hal/audio_hw.c b/hal/audio_hw.c index 3d98f064..78f11828 100644 --- a/hal/audio_hw.c +++ b/hal/audio_hw.c @@ -3347,10 +3347,12 @@ static int send_offload_cmd_l(struct stream_out* out, int command) return 0; } -/* must be called with out->lock and latch lock */ +/* must be called with out->lock */ 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) { @@ -3608,11 +3610,9 @@ static int create_offload_callback_thread(struct stream_out *out) static int destroy_offload_callback_thread(struct stream_out *out) { lock_output_stream(out); - pthread_mutex_lock(&out->latch_lock); stop_compressed_output_l(out); send_offload_cmd_l(out, OFFLOAD_CMD_EXIT); - pthread_mutex_unlock(&out->latch_lock); pthread_mutex_unlock(&out->lock); pthread_join(out->offload_thread, (void **) NULL); pthread_cond_destroy(&out->offload_cond); @@ -4507,9 +4507,7 @@ static int out_standby(struct audio_stream *stream) adev->adm_deregister_stream(adev->adm_data, out->handle); if (is_offload_usecase(out->usecase)) { - pthread_mutex_lock(&out->latch_lock); stop_compressed_output_l(out); - pthread_mutex_unlock(&out->latch_lock); } pthread_mutex_lock(&adev->lock); @@ -4584,9 +4582,7 @@ static int out_on_error(struct audio_stream *stream) // is needed e.g. when SSR happens within compress_open // since the stream is active, offload_callback_thread is also active. if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) { - pthread_mutex_lock(&out->latch_lock); stop_compressed_output_l(out); - pthread_mutex_unlock(&out->latch_lock); } pthread_mutex_unlock(&out->lock); @@ -4625,9 +4621,7 @@ int out_standby_l(struct audio_stream *stream) adev->adm_deregister_stream(adev->adm_data, out->handle); if (is_offload_usecase(out->usecase)) { - pthread_mutex_lock(&out->latch_lock); stop_compressed_output_l(out); - pthread_mutex_unlock(&out->latch_lock); } out->standby = true; @@ -6470,12 +6464,13 @@ static int out_flush(struct audio_stream_out* stream) lock_output_stream(out); pthread_mutex_lock(&out->latch_lock); if (out->offload_state == OFFLOAD_STATE_PAUSED) { + pthread_mutex_unlock(&out->latch_lock); stop_compressed_output_l(out); } else { ALOGW("%s called in invalid state %d", __func__, out->offload_state); + pthread_mutex_unlock(&out->latch_lock); } out->written = 0; - pthread_mutex_unlock(&out->latch_lock); pthread_mutex_unlock(&out->lock); ALOGD("copl(%p):out of compress flush", out); return 0; |