audio: fix memory corruption.
Race condition:
There is a race condition between audio primary hal thread and soundtrigger
hal thread when they want to get snd_card number.
Memory leakage:
my_data.kvpairs in platforom_info_init function doesn't be destroyed
when use str_parms_create().
Bug: 119328981
Test: manual audio test
Change-Id: Ib86b3cf986a7213007bf9f073ef714a02b28a111
Signed-off-by: juyuchen <juyuchen@google.com>
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 79dd9e5..3a1877b 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -581,7 +581,7 @@
}
/* Initialize snd card name specific ids and/or backends*/
- if (snd_card_info_init(platform_info_file, my_data,
+ if (platform_info_init(platform_info_file, my_data, false,
&acdb_set_parameters) < 0) {
ALOGE("Failed to find platform_info_file");
goto cleanup;
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 2bf552c..2707c89 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -1132,7 +1132,8 @@
/* Initialize ACDB and PCM ID's */
strlcpy(platform_info_path, PLATFORM_INFO_XML_PATH, MAX_MIXER_XML_PATH);
resolve_config_file(platform_info_path);
- platform_info_init(platform_info_path, my_data);
+ platform_info_init(platform_info_path, my_data,
+ true, &platform_set_parameters);
my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
if (my_data->acdb_handle == NULL) {
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index d675a5d..6991a12 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -1653,7 +1653,8 @@
my_data->declared_mic_count = 0;
/* Initialize platform specific ids and/or backends*/
- platform_info_init(platform_info_file, my_data);
+ platform_info_init(platform_info_file, my_data,
+ true, &platform_set_parameters);
ALOGD("%s: Loading mixer file: %s", __func__, mixer_xml_file);
adev->audio_route = audio_route_init(snd_card_num, mixer_xml_file);
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 1a7d2c3..8e249da 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -117,11 +117,11 @@
bool platform_sound_trigger_usecase_needs_event(audio_usecase_t uc_id);
-/* From platform_info.c */
-int platform_info_init(const char *filename, void *);
-
typedef int (*set_parameters_fn)(void *platform, struct str_parms *parms);
-int snd_card_info_init(const char *filename, void *, set_parameters_fn);
+
+/* From platform_info.c */
+int platform_info_init(const char *filename, void *,
+ bool do_full_parse, set_parameters_fn);
int platform_get_usecase_index(const char * usecase);
int platform_set_usecase_pcm_id(audio_usecase_t usecase, int32_t type, int32_t pcm_id);
diff --git a/hal/platform_info.c b/hal/platform_info.c
index c89020d..0695592 100644
--- a/hal/platform_info.c
+++ b/hal/platform_info.c
@@ -25,6 +25,7 @@
#include "platform_api.h"
#include <platform.h>
#include <math.h>
+#include <pthread.h>
/*
* Mandatory microphone characteristics include: device_id, type, address, location, group,
@@ -82,17 +83,19 @@
[ACDB_METAINFO_KEY] = process_acdb_metainfo_key,
};
-static set_parameters_fn set_parameters = &platform_set_parameters;
-
static section_t section;
struct platform_info {
+ pthread_mutex_t lock;
bool do_full_parse;
void *platform;
struct str_parms *kvpairs;
+ set_parameters_fn set_parameters;
};
-static struct platform_info my_data = {true, NULL, NULL};
+static struct platform_info my_data = {PTHREAD_MUTEX_INITIALIZER,
+ true, NULL, NULL,
+ &platform_set_parameters};
struct audio_string_to_enum {
const char* name;
@@ -415,7 +418,7 @@
}
str_parms_add_str(my_data.kvpairs, (char*)attr[1], (char*)attr[3]);
- set_parameters(my_data.platform, my_data.kvpairs);
+ my_data.set_parameters(my_data.platform, my_data.kvpairs);
done:
return;
}
@@ -857,14 +860,8 @@
}
}
-int snd_card_info_init(const char *filename, void *platform, set_parameters_fn fn)
-{
- set_parameters = fn;
- my_data.do_full_parse = false;
- return platform_info_init(filename, platform);
-}
-
-int platform_info_init(const char *filename, void *platform)
+int platform_info_init(const char *filename, void *platform,
+ bool do_full_parse, set_parameters_fn fn)
{
XML_Parser parser;
FILE *file;
@@ -873,7 +870,6 @@
void *buf;
static const uint32_t kBufSize = 1024;
char platform_info_file_name[MIXER_PATH_MAX_LENGTH]= {0};
- section = ROOT;
if (filename == NULL) {
strlcpy(platform_info_file_name, PLATFORM_INFO_XML_PATH, MIXER_PATH_MAX_LENGTH);
@@ -899,8 +895,12 @@
goto err_close_file;
}
+ pthread_mutex_lock(&my_data.lock);
+ section = ROOT;
+ my_data.do_full_parse = do_full_parse;
my_data.platform = platform;
my_data.kvpairs = str_parms_create();
+ my_data.set_parameters = fn;
XML_SetElementHandler(parser, start_tag, end_tag);
@@ -931,10 +931,12 @@
break;
}
- set_parameters = &platform_set_parameters;
- my_data.do_full_parse = true;
-
err_free_parser:
+ if (my_data.kvpairs != NULL) {
+ str_parms_destroy(my_data.kvpairs);
+ my_data.kvpairs = NULL;
+ }
+ pthread_mutex_unlock(&my_data.lock);
XML_ParserFree(parser);
err_close_file:
fclose(file);