summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGautam Manam <gmanam@codeaurora.org>2020-12-24 14:08:04 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2020-12-29 22:01:37 -0800
commitfeeb11639df4160701777a5abc05be345e74d1eb (patch)
tree16407da7d08a7cb0db3b91847da1a164766ba9f6
parentd4e8ced33fbadf778459b4eb36d31343f3068a2f (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.c15
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;