summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f>2021-06-01 10:22:23 +0000
committervboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f>2021-06-01 10:22:23 +0000
commit75530ebf1973fde48ea72d74cc62bc5aa0ab5eef (patch)
tree7e8329792ddde93b14541880ccd83c92393ebd18
parentb72f2b2f1f35beaf6905d756bd835a9c3f834d9e (diff)
downloadVirtualBox-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.cpp74
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);
+}
+