diff options
author | vboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f> | 2021-06-01 10:22:23 +0000 |
---|---|---|
committer | vboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f> | 2021-06-01 10:22:23 +0000 |
commit | 75530ebf1973fde48ea72d74cc62bc5aa0ab5eef (patch) | |
tree | 7e8329792ddde93b14541880ccd83c92393ebd18 | |
parent | b72f2b2f1f35beaf6905d756bd835a9c3f834d9e (diff) | |
download | VirtualBox-svn-75530ebf1973fde48ea72d74cc62bc5aa0ab5eef.tar.gz |
DrvHostAudioAlsaStubs: Use RTOnce to make the init thread-safe and all. bugref:9890
git-svn-id: https://www.virtualbox.org/svn/vbox/trunk@89425 cfe28804-0f27-0410-a406-dd0f0b0b656f
-rw-r--r-- | src/VBox/Devices/Audio/DrvHostAudioAlsaStubs.cpp | 74 |
1 files changed, 38 insertions, 36 deletions
diff --git a/src/VBox/Devices/Audio/DrvHostAudioAlsaStubs.cpp b/src/VBox/Devices/Audio/DrvHostAudioAlsaStubs.cpp index 5816c939b68..39f7b5ff60f 100644 --- a/src/VBox/Devices/Audio/DrvHostAudioAlsaStubs.cpp +++ b/src/VBox/Devices/Audio/DrvHostAudioAlsaStubs.cpp @@ -17,9 +17,10 @@ #define LOG_GROUP LOG_GROUP_DRV_HOST_AUDIO #include <iprt/assert.h> +#include <iprt/err.h> #include <iprt/ldr.h> #include <VBox/log.h> -#include <iprt/err.h> +#include <iprt/once.h> #include <alsa/asoundlib.h> #include <errno.h> @@ -238,47 +239,48 @@ static SHARED_FUNC SharedFuncs[] = }; #undef ELEMENT -/** - * Try to dynamically load the ALSA libraries. This function is not - * thread-safe, and should be called before attempting to use any of the - * ALSA functions. - * - * @returns iprt status code - */ -int audioLoadAlsaLib(void) -{ - static enum { NO = 0, YES, FAIL } isLibLoaded = NO; - RTLDRMOD hLib; +/** Init once. */ +static RTONCE g_AlsaLibInitOnce = RTONCE_INITIALIZER; + +/** @callback_method_impl{FNRTONCE} */ +static DECLCALLBACK(int32_t) drvHostAudioAlsaLibInitOnce(void *pvUser) +{ + RT_NOREF(pvUser); LogFlowFunc(("\n")); - /* If this is not NO then the function has obviously been called twice, - which is likely to be a bug. */ - if (NO != isLibLoaded) - { - AssertMsgFailed(("isLibLoaded == %s\n", YES == isLibLoaded ? "YES" : "NO")); - return YES == isLibLoaded ? VINF_SUCCESS : VERR_NOT_SUPPORTED; - } - isLibLoaded = FAIL; - int rc = RTLdrLoad(VBOX_ALSA_LIB, &hLib); - if (RT_FAILURE(rc)) - { - LogRelFunc(("Failed to load library %s (%Rrc)\n", VBOX_ALSA_LIB, rc)); - return rc; - } - for (uintptr_t i = 0; i < RT_ELEMENTS(SharedFuncs); i++) + + RTLDRMOD hMod = NIL_RTLDRMOD; + int rc = RTLdrLoadSystemEx(VBOX_ALSA_LIB, RTLDRLOAD_FLAGS_NO_UNLOAD, &hMod); + if (RT_SUCCESS(rc)) { - rc = RTLdrGetSymbol(hLib, SharedFuncs[i].name, (void **)SharedFuncs[i].pfn); - if (RT_SUCCESS(rc)) - { /* likely */ } - else if (SharedFuncs[i].pfnFallback && rc == VERR_SYMBOL_NOT_FOUND) - *SharedFuncs[i].pfn = SharedFuncs[i].pfnFallback; - else + for (uintptr_t i = 0; i < RT_ELEMENTS(SharedFuncs); i++) { - LogRelFunc(("Failed to load library %s: Getting symbol %s failed: %Rrc\n", VBOX_ALSA_LIB, SharedFuncs[i].name, rc)); - return rc; + rc = RTLdrGetSymbol(hMod, SharedFuncs[i].name, (void **)SharedFuncs[i].pfn); + if (RT_SUCCESS(rc)) + { /* likely */ } + else if (SharedFuncs[i].pfnFallback && rc == VERR_SYMBOL_NOT_FOUND) + *SharedFuncs[i].pfn = SharedFuncs[i].pfnFallback; + else + { + LogRelFunc(("Failed to load library %s: Getting symbol %s failed: %Rrc\n", VBOX_ALSA_LIB, SharedFuncs[i].name, rc)); + return rc; + } } } - isLibLoaded = YES; + else + LogRelFunc(("Failed to load library %s (%Rrc)\n", VBOX_ALSA_LIB, rc)); return rc; } + +/** + * Try to dynamically load the ALSA libraries. + * + * @returns VBox status code. + */ +int audioLoadAlsaLib(void) +{ + LogFlowFunc(("\n")); + return RTOnce(&g_AlsaLibInitOnce, drvHostAudioAlsaLibInitOnce, NULL); +} + |