hal: Remove in_get_stream and out_get_stream
Remove in_get_stream and out_get_stream and add in_ctxt and out_ctxt members to stream_in/out structs to track and directly access stream contexts. Mitigate race conditions with the active_in/outputs_list when in/out_get_stream reads the list. Change-Id: Iefc77d3c862b16dce8086e1afba15cf0210155b4
This commit is contained in:
parent
82a2664ca6
commit
6dd13096c1
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2013-2021, The Linux Foundation. All rights reserved.
|
||||
* Not a Contribution.
|
||||
*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
|
@ -6228,8 +6228,6 @@ int audio_extn_auto_hal_init(struct audio_device *adev)
|
|||
{
|
||||
if(auto_hal_init) {
|
||||
auto_hal_init_config_t auto_hal_init_config;
|
||||
auto_hal_init_config.fp_in_get_stream = in_get_stream;
|
||||
auto_hal_init_config.fp_out_get_stream = out_get_stream;
|
||||
auto_hal_init_config.fp_audio_extn_ext_hw_plugin_usecase_start = audio_extn_ext_hw_plugin_usecase_start;
|
||||
auto_hal_init_config.fp_audio_extn_ext_hw_plugin_usecase_stop = audio_extn_ext_hw_plugin_usecase_stop;
|
||||
auto_hal_init_config.fp_get_usecase_from_list = get_usecase_from_list;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2013-2021, The Linux Foundation. All rights reserved.
|
||||
* Not a Contribution.
|
||||
*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
|
@ -1390,16 +1390,12 @@ snd_device_t audio_extn_auto_hal_get_output_snd_device(struct audio_device *adev
|
|||
audio_usecase_t uc_id);
|
||||
snd_device_t audio_extn_auto_hal_get_snd_device_for_car_audio_stream(int car_audio_stream);
|
||||
|
||||
typedef streams_input_ctxt_t* (*fp_in_get_stream_t)(struct audio_device*, audio_io_handle_t);
|
||||
typedef streams_output_ctxt_t* (*fp_out_get_stream_t)(struct audio_device*, audio_io_handle_t);
|
||||
typedef size_t (*fp_get_output_period_size_t)(uint32_t, audio_format_t, int, int);
|
||||
typedef int (*fp_audio_extn_ext_hw_plugin_set_audio_gain_t)(void*, struct audio_usecase*, uint32_t);
|
||||
typedef struct stream_in* (*fp_adev_get_active_input_t)(const struct audio_device*);
|
||||
typedef audio_patch_handle_t (*fp_generate_patch_handle_t)(void);
|
||||
|
||||
typedef struct auto_hal_init_config {
|
||||
fp_in_get_stream_t fp_in_get_stream;
|
||||
fp_out_get_stream_t fp_out_get_stream;
|
||||
fp_audio_extn_ext_hw_plugin_usecase_start_t fp_audio_extn_ext_hw_plugin_usecase_start;
|
||||
fp_audio_extn_ext_hw_plugin_usecase_stop_t fp_audio_extn_ext_hw_plugin_usecase_stop;
|
||||
fp_get_usecase_from_list_t fp_get_usecase_from_list;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
@ -47,8 +47,6 @@
|
|||
#endif
|
||||
|
||||
//external feature dependency
|
||||
static fp_in_get_stream_t fp_in_get_stream;
|
||||
static fp_out_get_stream_t fp_out_get_stream;
|
||||
static fp_audio_extn_ext_hw_plugin_usecase_start_t fp_audio_extn_ext_hw_plugin_usecase_start;
|
||||
static fp_audio_extn_ext_hw_plugin_usecase_stop_t fp_audio_extn_ext_hw_plugin_usecase_stop;
|
||||
static fp_get_usecase_from_list_t fp_get_usecase_from_list;
|
||||
|
@ -937,8 +935,6 @@ int auto_hal_init(struct audio_device *adev, auto_hal_init_config_t init_config)
|
|||
|
||||
auto_hal->adev = adev;
|
||||
|
||||
fp_in_get_stream = init_config.fp_in_get_stream;
|
||||
fp_out_get_stream = init_config.fp_out_get_stream;
|
||||
fp_audio_extn_ext_hw_plugin_usecase_start = init_config.fp_audio_extn_ext_hw_plugin_usecase_start;
|
||||
fp_audio_extn_ext_hw_plugin_usecase_stop = init_config.fp_audio_extn_ext_hw_plugin_usecase_stop;
|
||||
fp_get_usecase_from_list = init_config.fp_get_usecase_from_list;
|
||||
|
|
|
@ -7440,38 +7440,6 @@ static int in_remove_audio_effect(const struct audio_stream *stream,
|
|||
return add_remove_audio_effect(stream, effect, false);
|
||||
}
|
||||
|
||||
streams_input_ctxt_t *in_get_stream(struct audio_device *dev,
|
||||
audio_io_handle_t input)
|
||||
{
|
||||
struct listnode *node;
|
||||
|
||||
list_for_each(node, &dev->active_inputs_list) {
|
||||
streams_input_ctxt_t *in_ctxt = node_to_item(node,
|
||||
streams_input_ctxt_t,
|
||||
list);
|
||||
if (in_ctxt->input->capture_handle == input) {
|
||||
return in_ctxt;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
streams_output_ctxt_t *out_get_stream(struct audio_device *dev,
|
||||
audio_io_handle_t output)
|
||||
{
|
||||
struct listnode *node;
|
||||
|
||||
list_for_each(node, &dev->active_outputs_list) {
|
||||
streams_output_ctxt_t *out_ctxt = node_to_item(node,
|
||||
streams_output_ctxt_t,
|
||||
list);
|
||||
if (out_ctxt->output->handle == output) {
|
||||
return out_ctxt;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int in_stop(const struct audio_stream_in* stream)
|
||||
{
|
||||
struct stream_in *in = (struct stream_in *)stream;
|
||||
|
@ -7797,15 +7765,6 @@ int adev_open_output_stream(struct audio_hw_device *dev,
|
|||
|
||||
*stream_out = NULL;
|
||||
|
||||
pthread_mutex_lock(&adev->lock);
|
||||
if (out_get_stream(adev, handle) != NULL) {
|
||||
ALOGW("%s, output stream already opened", __func__);
|
||||
ret = -EEXIST;
|
||||
}
|
||||
pthread_mutex_unlock(&adev->lock);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
|
||||
|
||||
ALOGD("%s: enter: format(%#x) sample_rate(%d) channel_mask(%#x) devices(%#x) flags(%#x)\
|
||||
|
@ -8643,17 +8602,10 @@ int adev_open_output_stream(struct audio_hw_device *dev,
|
|||
if (ret != 0)
|
||||
goto error_open;
|
||||
|
||||
streams_output_ctxt_t *out_ctxt = (streams_output_ctxt_t *)
|
||||
calloc(1, sizeof(streams_output_ctxt_t));
|
||||
if (out_ctxt == NULL) {
|
||||
ALOGE("%s fail to allocate output ctxt", __func__);
|
||||
ret = -ENOMEM;
|
||||
goto error_open;
|
||||
}
|
||||
out_ctxt->output = out;
|
||||
out->out_ctxt.output = out;
|
||||
|
||||
pthread_mutex_lock(&adev->lock);
|
||||
list_add_tail(&adev->active_outputs_list, &out_ctxt->list);
|
||||
list_add_tail(&adev->active_outputs_list, &out->out_ctxt.list);
|
||||
pthread_mutex_unlock(&adev->lock);
|
||||
|
||||
ALOGV("%s: exit", __func__);
|
||||
|
@ -8679,6 +8631,12 @@ void adev_close_output_stream(struct audio_hw_device *dev __unused,
|
|||
|
||||
io_streams_map_remove(adev, out->handle);
|
||||
|
||||
// remove out_ctxt early to prevent the stream
|
||||
// being opened in a race condition
|
||||
pthread_mutex_lock(&adev->lock);
|
||||
list_remove(&out->out_ctxt.list);
|
||||
pthread_mutex_unlock(&adev->lock);
|
||||
|
||||
// must deregister from sndmonitor first to prevent races
|
||||
// between the callback and close_stream
|
||||
audio_extn_snd_mon_unregister_listener(out);
|
||||
|
@ -8741,13 +8699,6 @@ void adev_close_output_stream(struct audio_hw_device *dev __unused,
|
|||
pthread_mutex_destroy(&out->position_query_lock);
|
||||
|
||||
pthread_mutex_lock(&adev->lock);
|
||||
streams_output_ctxt_t *out_ctxt = out_get_stream(adev, out->handle);
|
||||
if (out_ctxt != NULL) {
|
||||
list_remove(&out_ctxt->list);
|
||||
free(out_ctxt);
|
||||
} else {
|
||||
ALOGW("%s, output stream already closed", __func__);
|
||||
}
|
||||
free(stream);
|
||||
pthread_mutex_unlock(&adev->lock);
|
||||
ALOGV("%s: exit", __func__);
|
||||
|
@ -9386,15 +9337,6 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&adev->lock);
|
||||
if (in_get_stream(adev, handle) != NULL) {
|
||||
ALOGW("%s, input stream already opened", __func__);
|
||||
ret = -EEXIST;
|
||||
}
|
||||
pthread_mutex_unlock(&adev->lock);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
|
||||
|
||||
if (!in) {
|
||||
|
@ -9781,17 +9723,10 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
|
|||
if (ret != 0)
|
||||
goto err_open;
|
||||
|
||||
streams_input_ctxt_t *in_ctxt = (streams_input_ctxt_t *)
|
||||
calloc(1, sizeof(streams_input_ctxt_t));
|
||||
if (in_ctxt == NULL) {
|
||||
ALOGE("%s fail to allocate input ctxt", __func__);
|
||||
ret = -ENOMEM;
|
||||
goto err_open;
|
||||
}
|
||||
in_ctxt->input = in;
|
||||
in->in_ctxt.input = in;
|
||||
|
||||
pthread_mutex_lock(&adev->lock);
|
||||
list_add_tail(&adev->active_inputs_list, &in_ctxt->list);
|
||||
list_add_tail(&adev->active_inputs_list, &in->in_ctxt.list);
|
||||
pthread_mutex_unlock(&adev->lock);
|
||||
|
||||
ALOGV("%s: exit", __func__);
|
||||
|
@ -9823,6 +9758,12 @@ static void adev_close_input_stream(struct audio_hw_device *dev,
|
|||
}
|
||||
io_streams_map_remove(adev, in->capture_handle);
|
||||
|
||||
// remove out_ctxt early to prevent the stream
|
||||
// being opened in a race condition
|
||||
pthread_mutex_lock(&adev->lock);
|
||||
list_remove(&in->in_ctxt.list);
|
||||
pthread_mutex_unlock(&adev->lock);
|
||||
|
||||
/* must deregister from sndmonitor first to prevent races
|
||||
* between the callback and close_stream
|
||||
*/
|
||||
|
@ -9885,13 +9826,6 @@ static void adev_close_input_stream(struct audio_hw_device *dev,
|
|||
ALOGV("%s: sound trigger pcm stop lab", __func__);
|
||||
audio_extn_sound_trigger_stop_lab(in);
|
||||
}
|
||||
streams_input_ctxt_t *in_ctxt = in_get_stream(adev, in->capture_handle);
|
||||
if (in_ctxt != NULL) {
|
||||
list_remove(&in_ctxt->list);
|
||||
free(in_ctxt);
|
||||
} else {
|
||||
ALOGW("%s, input stream already closed", __func__);
|
||||
}
|
||||
free(stream);
|
||||
pthread_mutex_unlock(&adev->lock);
|
||||
return;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2013-2021, The Linux Foundation. All rights reserved.
|
||||
* Not a contribution.
|
||||
*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
|
@ -361,6 +361,16 @@ struct stream_config {
|
|||
unsigned int bit_width;
|
||||
};
|
||||
|
||||
typedef struct streams_input_ctxt {
|
||||
struct listnode list;
|
||||
struct stream_in *input;
|
||||
} streams_input_ctxt_t;
|
||||
|
||||
typedef struct streams_output_ctxt {
|
||||
struct listnode list;
|
||||
struct stream_out *output;
|
||||
} streams_output_ctxt_t;
|
||||
|
||||
struct stream_inout {
|
||||
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 */
|
||||
|
@ -409,6 +419,7 @@ struct stream_out {
|
|||
int64_t mmap_time_offset_nanos; /* fudge factor to correct inaccuracies in DSP */
|
||||
int mmap_shared_memory_fd; /* file descriptor associated with MMAP NOIRQ shared memory */
|
||||
audio_io_handle_t handle;
|
||||
streams_output_ctxt_t out_ctxt;
|
||||
struct stream_app_type_cfg app_type_cfg;
|
||||
|
||||
int non_blocking;
|
||||
|
@ -515,6 +526,7 @@ struct stream_in {
|
|||
int64_t mmap_time_offset_nanos; /* fudge factor to correct inaccuracies in DSP */
|
||||
int mmap_shared_memory_fd; /* file descriptor associated with MMAP NOIRQ shared memory */
|
||||
audio_io_handle_t capture_handle;
|
||||
streams_input_ctxt_t in_ctxt;
|
||||
audio_input_flags_t flags;
|
||||
char profile[MAX_STREAM_PROFILE_STR_LEN];
|
||||
bool is_st_session;
|
||||
|
@ -623,16 +635,6 @@ struct streams_io_cfg {
|
|||
struct stream_app_type_cfg app_type_cfg;
|
||||
};
|
||||
|
||||
typedef struct streams_input_ctxt {
|
||||
struct listnode list;
|
||||
struct stream_in *input;
|
||||
} streams_input_ctxt_t;
|
||||
|
||||
typedef struct streams_output_ctxt {
|
||||
struct listnode list;
|
||||
struct stream_out *output;
|
||||
} streams_output_ctxt_t;
|
||||
|
||||
typedef void* (*adm_init_t)();
|
||||
typedef void (*adm_deinit_t)(void *);
|
||||
typedef void (*adm_register_output_stream_t)(void *, audio_io_handle_t, audio_output_flags_t);
|
||||
|
@ -814,11 +816,6 @@ void adev_close_output_stream(struct audio_hw_device *dev __unused,
|
|||
|
||||
bool is_interactive_usecase(audio_usecase_t uc_id);
|
||||
|
||||
streams_input_ctxt_t *in_get_stream(struct audio_device *dev,
|
||||
audio_io_handle_t input);
|
||||
streams_output_ctxt_t *out_get_stream(struct audio_device *dev,
|
||||
audio_io_handle_t output);
|
||||
|
||||
size_t get_output_period_size(uint32_t sample_rate,
|
||||
audio_format_t format,
|
||||
int channel_count,
|
||||
|
|
Loading…
Reference in New Issue