Use C++ a bit more with alc.cpp
This commit is contained in:
parent
3021a426c0
commit
46301a087c
246
Alc/alc.cpp
246
Alc/alc.cpp
@ -30,6 +30,8 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <mutex>
|
||||||
|
#include <thread>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@ -58,6 +60,8 @@
|
|||||||
#include "backends/base.h"
|
#include "backends/base.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
/************************************************
|
/************************************************
|
||||||
* Backends
|
* Backends
|
||||||
************************************************/
|
************************************************/
|
||||||
@ -66,7 +70,7 @@ struct BackendInfo {
|
|||||||
ALCbackendFactory* (*getFactory)(void);
|
ALCbackendFactory* (*getFactory)(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct BackendInfo BackendList[] = {
|
struct BackendInfo BackendList[] = {
|
||||||
#ifdef HAVE_JACK
|
#ifdef HAVE_JACK
|
||||||
{ "jack", ALCjackBackendFactory_getFactory },
|
{ "jack", ALCjackBackendFactory_getFactory },
|
||||||
#endif
|
#endif
|
||||||
@ -115,18 +119,18 @@ static struct BackendInfo BackendList[] = {
|
|||||||
{ "wave", ALCwaveBackendFactory_getFactory },
|
{ "wave", ALCwaveBackendFactory_getFactory },
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
static ALsizei BackendListSize = COUNTOF(BackendList);
|
ALsizei BackendListSize = COUNTOF(BackendList);
|
||||||
#undef EmptyFuncs
|
#undef EmptyFuncs
|
||||||
|
|
||||||
static struct BackendInfo PlaybackBackend;
|
struct BackendInfo PlaybackBackend;
|
||||||
static struct BackendInfo CaptureBackend;
|
struct BackendInfo CaptureBackend;
|
||||||
|
|
||||||
|
|
||||||
/************************************************
|
/************************************************
|
||||||
* Functions, enums, and errors
|
* Functions, enums, and errors
|
||||||
************************************************/
|
************************************************/
|
||||||
#define DECL(x) { #x, (ALCvoid*)(x) }
|
#define DECL(x) { #x, (ALCvoid*)(x) }
|
||||||
static const struct {
|
constexpr struct {
|
||||||
const ALCchar *funcName;
|
const ALCchar *funcName;
|
||||||
ALCvoid *address;
|
ALCvoid *address;
|
||||||
} alcFunctions[] = {
|
} alcFunctions[] = {
|
||||||
@ -305,7 +309,7 @@ static const struct {
|
|||||||
#undef DECL
|
#undef DECL
|
||||||
|
|
||||||
#define DECL(x) { #x, (x) }
|
#define DECL(x) { #x, (x) }
|
||||||
static const struct {
|
constexpr struct {
|
||||||
const ALCchar *enumName;
|
const ALCchar *enumName;
|
||||||
ALCenum value;
|
ALCenum value;
|
||||||
} alcEnumerations[] = {
|
} alcEnumerations[] = {
|
||||||
@ -688,12 +692,12 @@ static const struct {
|
|||||||
};
|
};
|
||||||
#undef DECL
|
#undef DECL
|
||||||
|
|
||||||
static const ALCchar alcNoError[] = "No Error";
|
constexpr ALCchar alcNoError[] = "No Error";
|
||||||
static const ALCchar alcErrInvalidDevice[] = "Invalid Device";
|
constexpr ALCchar alcErrInvalidDevice[] = "Invalid Device";
|
||||||
static const ALCchar alcErrInvalidContext[] = "Invalid Context";
|
constexpr ALCchar alcErrInvalidContext[] = "Invalid Context";
|
||||||
static const ALCchar alcErrInvalidEnum[] = "Invalid Enum";
|
constexpr ALCchar alcErrInvalidEnum[] = "Invalid Enum";
|
||||||
static const ALCchar alcErrInvalidValue[] = "Invalid Value";
|
constexpr ALCchar alcErrInvalidValue[] = "Invalid Value";
|
||||||
static const ALCchar alcErrOutOfMemory[] = "Out of Memory";
|
constexpr ALCchar alcErrOutOfMemory[] = "Out of Memory";
|
||||||
|
|
||||||
|
|
||||||
/************************************************
|
/************************************************
|
||||||
@ -701,17 +705,17 @@ static const ALCchar alcErrOutOfMemory[] = "Out of Memory";
|
|||||||
************************************************/
|
************************************************/
|
||||||
|
|
||||||
/* Enumerated device names */
|
/* Enumerated device names */
|
||||||
static const ALCchar alcDefaultName[] = "OpenAL Soft\0";
|
constexpr ALCchar alcDefaultName[] = "OpenAL Soft\0";
|
||||||
|
|
||||||
static al_string alcAllDevicesList;
|
al_string alcAllDevicesList;
|
||||||
static al_string alcCaptureDeviceList;
|
al_string alcCaptureDeviceList;
|
||||||
|
|
||||||
/* Default is always the first in the list */
|
/* Default is always the first in the list */
|
||||||
static ALCchar *alcDefaultAllDevicesSpecifier;
|
std::string alcDefaultAllDevicesSpecifier;
|
||||||
static ALCchar *alcCaptureDefaultDeviceSpecifier;
|
std::string alcCaptureDefaultDeviceSpecifier;
|
||||||
|
|
||||||
/* Default context extensions */
|
/* Default context extensions */
|
||||||
static const ALchar alExtList[] =
|
constexpr ALchar alExtList[] =
|
||||||
"AL_EXT_ALAW "
|
"AL_EXT_ALAW "
|
||||||
"AL_EXT_BFORMAT "
|
"AL_EXT_BFORMAT "
|
||||||
"AL_EXT_DOUBLE "
|
"AL_EXT_DOUBLE "
|
||||||
@ -742,12 +746,54 @@ static const ALchar alExtList[] =
|
|||||||
"AL_SOFT_source_resampler "
|
"AL_SOFT_source_resampler "
|
||||||
"AL_SOFT_source_spatialize";
|
"AL_SOFT_source_spatialize";
|
||||||
|
|
||||||
static ATOMIC(ALCenum) LastNullDeviceError = ATOMIC_INIT_STATIC(ALC_NO_ERROR);
|
std::atomic<ALCenum> LastNullDeviceError{ALC_NO_ERROR};
|
||||||
|
|
||||||
/* Thread-local current context */
|
/* Thread-local current context */
|
||||||
static altss_t LocalContext;
|
altss_t LocalContext;
|
||||||
/* Process-wide current context */
|
/* Process-wide current context */
|
||||||
static ATOMIC(ALCcontext*) GlobalContext = ATOMIC_INIT_STATIC(nullptr);
|
std::atomic<ALCcontext*> GlobalContext{nullptr};
|
||||||
|
|
||||||
|
/* Flag to trap ALC device errors */
|
||||||
|
bool TrapALCError{false};
|
||||||
|
|
||||||
|
/* One-time configuration init control */
|
||||||
|
std::once_flag alc_config_once{};
|
||||||
|
|
||||||
|
/* Default effect that applies to sources that don't have an effect on send 0 */
|
||||||
|
ALeffect DefaultEffect;
|
||||||
|
|
||||||
|
/* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
|
||||||
|
* updates.
|
||||||
|
*/
|
||||||
|
bool SuspendDefers{true};
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************
|
||||||
|
* ALC information
|
||||||
|
************************************************/
|
||||||
|
constexpr ALCchar alcNoDeviceExtList[] =
|
||||||
|
"ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
|
||||||
|
"ALC_EXT_thread_local_context ALC_SOFT_loopback";
|
||||||
|
constexpr ALCchar alcExtensionList[] =
|
||||||
|
"ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
|
||||||
|
"ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
|
||||||
|
"ALC_EXT_thread_local_context ALC_SOFT_device_clock ALC_SOFT_HRTF "
|
||||||
|
"ALC_SOFT_loopback ALC_SOFT_output_limiter ALC_SOFT_pause_device";
|
||||||
|
constexpr ALCint alcMajorVersion = 1;
|
||||||
|
constexpr ALCint alcMinorVersion = 1;
|
||||||
|
|
||||||
|
constexpr ALCint alcEFXMajorVersion = 1;
|
||||||
|
constexpr ALCint alcEFXMinorVersion = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************
|
||||||
|
* Device lists
|
||||||
|
************************************************/
|
||||||
|
std::atomic<ALCdevice*> DeviceList{nullptr};
|
||||||
|
|
||||||
|
std::recursive_mutex ListLock;
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
/* Mixing thread piority level */
|
/* Mixing thread piority level */
|
||||||
ALint RTPrioLevel;
|
ALint RTPrioLevel;
|
||||||
@ -759,56 +805,6 @@ enum LogLevel LogLevel = LogWarning;
|
|||||||
enum LogLevel LogLevel = LogError;
|
enum LogLevel LogLevel = LogError;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Flag to trap ALC device errors */
|
|
||||||
static ALCboolean TrapALCError = ALC_FALSE;
|
|
||||||
|
|
||||||
/* One-time configuration init control */
|
|
||||||
static alonce_flag alc_config_once = AL_ONCE_FLAG_INIT;
|
|
||||||
|
|
||||||
/* Default effect that applies to sources that don't have an effect on send 0 */
|
|
||||||
static ALeffect DefaultEffect;
|
|
||||||
|
|
||||||
/* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
|
|
||||||
* updates.
|
|
||||||
*/
|
|
||||||
static ALCboolean SuspendDefers = ALC_TRUE;
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************
|
|
||||||
* ALC information
|
|
||||||
************************************************/
|
|
||||||
static const ALCchar alcNoDeviceExtList[] =
|
|
||||||
"ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
|
|
||||||
"ALC_EXT_thread_local_context ALC_SOFT_loopback";
|
|
||||||
static const ALCchar alcExtensionList[] =
|
|
||||||
"ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
|
|
||||||
"ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
|
|
||||||
"ALC_EXT_thread_local_context ALC_SOFT_device_clock ALC_SOFT_HRTF "
|
|
||||||
"ALC_SOFT_loopback ALC_SOFT_output_limiter ALC_SOFT_pause_device";
|
|
||||||
static const ALCint alcMajorVersion = 1;
|
|
||||||
static const ALCint alcMinorVersion = 1;
|
|
||||||
|
|
||||||
static const ALCint alcEFXMajorVersion = 1;
|
|
||||||
static const ALCint alcEFXMinorVersion = 0;
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************
|
|
||||||
* Device lists
|
|
||||||
************************************************/
|
|
||||||
static std::atomic<ALCdevice*> DeviceList{nullptr};
|
|
||||||
|
|
||||||
static almtx_t ListLock;
|
|
||||||
static inline void LockLists(void)
|
|
||||||
{
|
|
||||||
int ret = almtx_lock(&ListLock);
|
|
||||||
assert(ret == althrd_success);
|
|
||||||
}
|
|
||||||
static inline void UnlockLists(void)
|
|
||||||
{
|
|
||||||
int ret = almtx_unlock(&ListLock);
|
|
||||||
assert(ret == althrd_success);
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************************************
|
/************************************************
|
||||||
* Library initialization
|
* Library initialization
|
||||||
************************************************/
|
************************************************/
|
||||||
@ -899,9 +895,6 @@ static void alc_init(void)
|
|||||||
|
|
||||||
ret = altss_create(&LocalContext, ReleaseThreadCtx);
|
ret = altss_create(&LocalContext, ReleaseThreadCtx);
|
||||||
assert(ret == althrd_success);
|
assert(ret == althrd_success);
|
||||||
|
|
||||||
ret = almtx_init(&ListLock, almtx_recursive);
|
|
||||||
assert(ret == althrd_success);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void alc_initconfig(void)
|
static void alc_initconfig(void)
|
||||||
@ -951,7 +944,7 @@ static void alc_initconfig(void)
|
|||||||
{
|
{
|
||||||
if(strcasecmp(str, "ignore") == 0)
|
if(strcasecmp(str, "ignore") == 0)
|
||||||
{
|
{
|
||||||
SuspendDefers = ALC_FALSE;
|
SuspendDefers = false;
|
||||||
TRACE("Selected context suspend behavior, \"ignore\"\n");
|
TRACE("Selected context suspend behavior, \"ignore\"\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1023,7 +1016,7 @@ static void alc_initconfig(void)
|
|||||||
if(str && (strcasecmp(str, "true") == 0 || strtol(str, nullptr, 0) == 1))
|
if(str && (strcasecmp(str, "true") == 0 || strtol(str, nullptr, 0) == 1))
|
||||||
{
|
{
|
||||||
TrapALError = AL_TRUE;
|
TrapALError = AL_TRUE;
|
||||||
TrapALCError = AL_TRUE;
|
TrapALCError = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1034,8 +1027,8 @@ static void alc_initconfig(void)
|
|||||||
|
|
||||||
str = getenv("ALSOFT_TRAP_ALC_ERROR");
|
str = getenv("ALSOFT_TRAP_ALC_ERROR");
|
||||||
if(str && (strcasecmp(str, "true") == 0 || strtol(str, nullptr, 0) == 1))
|
if(str && (strcasecmp(str, "true") == 0 || strtol(str, nullptr, 0) == 1))
|
||||||
TrapALCError = ALC_TRUE;
|
TrapALCError = true;
|
||||||
TrapALCError = GetConfigValueBool(nullptr, nullptr, "trap-alc-error", TrapALCError);
|
TrapALCError = !!GetConfigValueBool(nullptr, nullptr, "trap-alc-error", TrapALCError);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ConfigValueFloat(nullptr, "reverb", "boost", &valf))
|
if(ConfigValueFloat(nullptr, "reverb", "boost", &valf))
|
||||||
@ -1172,7 +1165,7 @@ static void alc_initconfig(void)
|
|||||||
if((str && str[0]) || ConfigValueStr(nullptr, nullptr, "default-reverb", &str))
|
if((str && str[0]) || ConfigValueStr(nullptr, nullptr, "default-reverb", &str))
|
||||||
LoadReverbPreset(str, &DefaultEffect);
|
LoadReverbPreset(str, &DefaultEffect);
|
||||||
}
|
}
|
||||||
#define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
|
#define DO_INITCONFIG() std::call_once(alc_config_once, alc_initconfig)
|
||||||
|
|
||||||
|
|
||||||
/************************************************
|
/************************************************
|
||||||
@ -1183,10 +1176,8 @@ static void alc_cleanup(void)
|
|||||||
AL_STRING_DEINIT(alcAllDevicesList);
|
AL_STRING_DEINIT(alcAllDevicesList);
|
||||||
AL_STRING_DEINIT(alcCaptureDeviceList);
|
AL_STRING_DEINIT(alcCaptureDeviceList);
|
||||||
|
|
||||||
free(alcDefaultAllDevicesSpecifier);
|
alcDefaultAllDevicesSpecifier.clear();
|
||||||
alcDefaultAllDevicesSpecifier = nullptr;
|
alcCaptureDefaultDeviceSpecifier.clear();
|
||||||
free(alcCaptureDefaultDeviceSpecifier);
|
|
||||||
alcCaptureDefaultDeviceSpecifier = nullptr;
|
|
||||||
|
|
||||||
if(ALCdevice *dev{DeviceList.exchange(nullptr)})
|
if(ALCdevice *dev{DeviceList.exchange(nullptr)})
|
||||||
{
|
{
|
||||||
@ -1206,7 +1197,6 @@ static void alc_deinit_safe(void)
|
|||||||
FreeHrtfs();
|
FreeHrtfs();
|
||||||
FreeALConfig();
|
FreeALConfig();
|
||||||
|
|
||||||
almtx_destroy(&ListLock);
|
|
||||||
altss_delete(LocalContext);
|
altss_delete(LocalContext);
|
||||||
|
|
||||||
if(LogFile != stderr)
|
if(LogFile != stderr)
|
||||||
@ -1246,16 +1236,13 @@ static void ProbeDevices(al_string *list, struct BackendInfo *backendinfo, enum
|
|||||||
{
|
{
|
||||||
DO_INITCONFIG();
|
DO_INITCONFIG();
|
||||||
|
|
||||||
LockLists();
|
std::lock_guard<std::recursive_mutex> _{ListLock};
|
||||||
alstr_clear(list);
|
alstr_clear(list);
|
||||||
|
|
||||||
if(backendinfo->getFactory)
|
if(backendinfo->getFactory)
|
||||||
{
|
{
|
||||||
ALCbackendFactory *factory = backendinfo->getFactory();
|
ALCbackendFactory *factory = backendinfo->getFactory();
|
||||||
V(factory,probe)(type, list);
|
V(factory,probe)(type, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
UnlockLists();
|
|
||||||
}
|
}
|
||||||
static void ProbeAllDevicesList(void)
|
static void ProbeAllDevicesList(void)
|
||||||
{ ProbeDevices(&alcAllDevicesList, &PlaybackBackend, ALL_DEVICE_PROBE); }
|
{ ProbeDevices(&alcAllDevicesList, &PlaybackBackend, ALL_DEVICE_PROBE); }
|
||||||
@ -1634,7 +1621,7 @@ static void alcSetError(ALCdevice *device, ALCenum errorCode)
|
|||||||
if(device)
|
if(device)
|
||||||
ATOMIC_STORE_SEQ(&device->LastError, errorCode);
|
ATOMIC_STORE_SEQ(&device->LastError, errorCode);
|
||||||
else
|
else
|
||||||
ATOMIC_STORE_SEQ(&LastNullDeviceError, errorCode);
|
LastNullDeviceError.store(errorCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2311,8 +2298,8 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
|
|||||||
* auxiliary sends is changing. Active sources will have updates
|
* auxiliary sends is changing. Active sources will have updates
|
||||||
* respecified in UpdateAllSourceProps.
|
* respecified in UpdateAllSourceProps.
|
||||||
*/
|
*/
|
||||||
vprops = ATOMIC_EXCHANGE_PTR(&context->FreeVoiceProps, static_cast<ALvoiceProps*>(nullptr),
|
vprops = static_cast<ALvoiceProps*>(ATOMIC_EXCHANGE_PTR(&context->FreeVoiceProps,
|
||||||
almemory_order_acq_rel);
|
static_cast<ALvoiceProps*>(nullptr), almemory_order_acq_rel));
|
||||||
while(vprops)
|
while(vprops)
|
||||||
{
|
{
|
||||||
struct ALvoiceProps *next = ATOMIC_LOAD(&vprops->next, almemory_order_relaxed);
|
struct ALvoiceProps *next = ATOMIC_LOAD(&vprops->next, almemory_order_relaxed);
|
||||||
@ -2537,19 +2524,17 @@ void ALCdevice_DecRef(ALCdevice *device)
|
|||||||
*/
|
*/
|
||||||
static ALCboolean VerifyDevice(ALCdevice **device)
|
static ALCboolean VerifyDevice(ALCdevice **device)
|
||||||
{
|
{
|
||||||
LockLists();
|
std::lock_guard<std::recursive_mutex> _{ListLock};
|
||||||
ALCdevice *tmpDevice{DeviceList.load()};
|
ALCdevice *tmpDevice{DeviceList.load()};
|
||||||
while(tmpDevice)
|
while(tmpDevice)
|
||||||
{
|
{
|
||||||
if(tmpDevice == *device)
|
if(tmpDevice == *device)
|
||||||
{
|
{
|
||||||
ALCdevice_IncRef(tmpDevice);
|
ALCdevice_IncRef(tmpDevice);
|
||||||
UnlockLists();
|
|
||||||
return ALC_TRUE;
|
return ALC_TRUE;
|
||||||
}
|
}
|
||||||
tmpDevice = ATOMIC_LOAD(&tmpDevice->next, almemory_order_relaxed);
|
tmpDevice = ATOMIC_LOAD(&tmpDevice->next, almemory_order_relaxed);
|
||||||
}
|
}
|
||||||
UnlockLists();
|
|
||||||
|
|
||||||
*device = nullptr;
|
*device = nullptr;
|
||||||
return ALC_FALSE;
|
return ALC_FALSE;
|
||||||
@ -2661,7 +2646,6 @@ static ALvoid InitContext(ALCcontext *Context)
|
|||||||
static void FreeContext(ALCcontext *context)
|
static void FreeContext(ALCcontext *context)
|
||||||
{
|
{
|
||||||
ALlistener *listener = context->Listener;
|
ALlistener *listener = context->Listener;
|
||||||
struct ALeffectslotArray *auxslots;
|
|
||||||
struct ALeffectslotProps *eprops;
|
struct ALeffectslotProps *eprops;
|
||||||
struct ALlistenerProps *lprops;
|
struct ALlistenerProps *lprops;
|
||||||
struct ALcontextProps *cprops;
|
struct ALcontextProps *cprops;
|
||||||
@ -2694,9 +2678,8 @@ static void FreeContext(ALCcontext *context)
|
|||||||
context->DefaultSlot = nullptr;
|
context->DefaultSlot = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auxslots = ATOMIC_EXCHANGE_PTR(&context->ActiveAuxSlots,
|
al_free(ATOMIC_EXCHANGE_PTR(&context->ActiveAuxSlots,
|
||||||
static_cast<ALeffectslotArray*>(nullptr), almemory_order_relaxed);
|
static_cast<ALeffectslotArray*>(nullptr), almemory_order_relaxed));
|
||||||
al_free(auxslots);
|
|
||||||
|
|
||||||
ReleaseALSources(context);
|
ReleaseALSources(context);
|
||||||
#define FREE_SOURCESUBLIST(x) al_free((x)->Sources)
|
#define FREE_SOURCESUBLIST(x) al_free((x)->Sources)
|
||||||
@ -2795,7 +2778,7 @@ static bool ReleaseContext(ALCcontext *context, ALCdevice *device)
|
|||||||
}
|
}
|
||||||
|
|
||||||
origctx = context;
|
origctx = context;
|
||||||
if(ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&GlobalContext, &origctx, static_cast<ALCcontext*>(nullptr)))
|
if(GlobalContext.compare_exchange_strong(origctx, nullptr))
|
||||||
ALCcontext_DecRef(context);
|
ALCcontext_DecRef(context);
|
||||||
|
|
||||||
V0(device->Backend,lock)();
|
V0(device->Backend,lock)();
|
||||||
@ -2857,7 +2840,7 @@ static void ReleaseThreadCtx(void *ptr)
|
|||||||
*/
|
*/
|
||||||
static ALCboolean VerifyContext(ALCcontext **context)
|
static ALCboolean VerifyContext(ALCcontext **context)
|
||||||
{
|
{
|
||||||
LockLists();
|
std::lock_guard<std::recursive_mutex> _{ListLock};
|
||||||
ALCdevice *dev{DeviceList.load()};
|
ALCdevice *dev{DeviceList.load()};
|
||||||
while(dev)
|
while(dev)
|
||||||
{
|
{
|
||||||
@ -2867,14 +2850,12 @@ static ALCboolean VerifyContext(ALCcontext **context)
|
|||||||
if(ctx == *context)
|
if(ctx == *context)
|
||||||
{
|
{
|
||||||
ALCcontext_IncRef(ctx);
|
ALCcontext_IncRef(ctx);
|
||||||
UnlockLists();
|
|
||||||
return ALC_TRUE;
|
return ALC_TRUE;
|
||||||
}
|
}
|
||||||
ctx = ATOMIC_LOAD(&ctx->next, almemory_order_relaxed);
|
ctx = ATOMIC_LOAD(&ctx->next, almemory_order_relaxed);
|
||||||
}
|
}
|
||||||
dev = ATOMIC_LOAD(&dev->next, almemory_order_relaxed);
|
dev = ATOMIC_LOAD(&dev->next, almemory_order_relaxed);
|
||||||
}
|
}
|
||||||
UnlockLists();
|
|
||||||
|
|
||||||
*context = nullptr;
|
*context = nullptr;
|
||||||
return ALC_FALSE;
|
return ALC_FALSE;
|
||||||
@ -2893,10 +2874,9 @@ ALCcontext *GetContextRef(void)
|
|||||||
ALCcontext_IncRef(context);
|
ALCcontext_IncRef(context);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LockLists();
|
std::lock_guard<std::recursive_mutex> _{ListLock};
|
||||||
context = ATOMIC_LOAD_SEQ(&GlobalContext);
|
context = GlobalContext.load(std::memory_order_acquire);
|
||||||
if(context) ALCcontext_IncRef(context);
|
if(context) ALCcontext_IncRef(context);
|
||||||
UnlockLists();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
@ -3007,7 +2987,7 @@ ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
|
|||||||
ALCdevice_DecRef(device);
|
ALCdevice_DecRef(device);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
errorCode = ATOMIC_EXCHANGE_SEQ(&LastNullDeviceError, ALC_NO_ERROR);
|
errorCode = LastNullDeviceError.exchange(ALC_NO_ERROR);
|
||||||
|
|
||||||
return errorCode;
|
return errorCode;
|
||||||
}
|
}
|
||||||
@ -3125,12 +3105,8 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum para
|
|||||||
|
|
||||||
VerifyDevice(&Device);
|
VerifyDevice(&Device);
|
||||||
|
|
||||||
free(alcDefaultAllDevicesSpecifier);
|
alcDefaultAllDevicesSpecifier = alstr_get_cstr(alcAllDevicesList);
|
||||||
alcDefaultAllDevicesSpecifier = strdup(alstr_get_cstr(alcAllDevicesList));
|
value = alcDefaultAllDevicesSpecifier.c_str();
|
||||||
if(!alcDefaultAllDevicesSpecifier)
|
|
||||||
alcSetError(Device, ALC_OUT_OF_MEMORY);
|
|
||||||
|
|
||||||
value = alcDefaultAllDevicesSpecifier;
|
|
||||||
if(Device) ALCdevice_DecRef(Device);
|
if(Device) ALCdevice_DecRef(Device);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -3140,12 +3116,8 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum para
|
|||||||
|
|
||||||
VerifyDevice(&Device);
|
VerifyDevice(&Device);
|
||||||
|
|
||||||
free(alcCaptureDefaultDeviceSpecifier);
|
alcCaptureDefaultDeviceSpecifier = alstr_get_cstr(alcCaptureDeviceList);
|
||||||
alcCaptureDefaultDeviceSpecifier = strdup(alstr_get_cstr(alcCaptureDeviceList));
|
value = alcCaptureDefaultDeviceSpecifier.c_str();
|
||||||
if(!alcCaptureDefaultDeviceSpecifier)
|
|
||||||
alcSetError(Device, ALC_OUT_OF_MEMORY);
|
|
||||||
|
|
||||||
value = alcCaptureDefaultDeviceSpecifier;
|
|
||||||
if(Device) ALCdevice_DecRef(Device);
|
if(Device) ALCdevice_DecRef(Device);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -3772,17 +3744,17 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin
|
|||||||
* device is asynchronously destropyed, to ensure this new context is
|
* device is asynchronously destropyed, to ensure this new context is
|
||||||
* properly cleaned up after being made.
|
* properly cleaned up after being made.
|
||||||
*/
|
*/
|
||||||
LockLists();
|
std::unique_lock<std::recursive_mutex> listlock{ListLock};
|
||||||
if(!VerifyDevice(&device) || device->Type == Capture ||
|
if(!VerifyDevice(&device) || device->Type == Capture ||
|
||||||
!ATOMIC_LOAD(&device->Connected, almemory_order_relaxed))
|
!ATOMIC_LOAD(&device->Connected, almemory_order_relaxed))
|
||||||
{
|
{
|
||||||
UnlockLists();
|
listlock.unlock();
|
||||||
alcSetError(device, ALC_INVALID_DEVICE);
|
alcSetError(device, ALC_INVALID_DEVICE);
|
||||||
if(device) ALCdevice_DecRef(device);
|
if(device) ALCdevice_DecRef(device);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
almtx_lock(&device->BackendLock);
|
almtx_lock(&device->BackendLock);
|
||||||
UnlockLists();
|
listlock.unlock();
|
||||||
|
|
||||||
ATOMIC_STORE_SEQ(&device->LastError, ALC_NO_ERROR);
|
ATOMIC_STORE_SEQ(&device->LastError, ALC_NO_ERROR);
|
||||||
|
|
||||||
@ -3889,17 +3861,15 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin
|
|||||||
*/
|
*/
|
||||||
ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
|
ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
|
||||||
{
|
{
|
||||||
ALCdevice *Device;
|
std::unique_lock<std::recursive_mutex> listlock{ListLock};
|
||||||
|
|
||||||
LockLists();
|
|
||||||
if(!VerifyContext(&context))
|
if(!VerifyContext(&context))
|
||||||
{
|
{
|
||||||
UnlockLists();
|
listlock.unlock();
|
||||||
alcSetError(nullptr, ALC_INVALID_CONTEXT);
|
alcSetError(nullptr, ALC_INVALID_CONTEXT);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Device = context->Device;
|
ALCdevice* Device{context->Device};
|
||||||
if(Device)
|
if(Device)
|
||||||
{
|
{
|
||||||
almtx_lock(&Device->BackendLock);
|
almtx_lock(&Device->BackendLock);
|
||||||
@ -3910,7 +3880,7 @@ ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
|
|||||||
}
|
}
|
||||||
almtx_unlock(&Device->BackendLock);
|
almtx_unlock(&Device->BackendLock);
|
||||||
}
|
}
|
||||||
UnlockLists();
|
listlock.unlock();
|
||||||
|
|
||||||
ALCcontext_DecRef(context);
|
ALCcontext_DecRef(context);
|
||||||
}
|
}
|
||||||
@ -3923,7 +3893,7 @@ ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
|
|||||||
ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
|
ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
|
||||||
{
|
{
|
||||||
ALCcontext *Context{static_cast<ALCcontext*>(altss_get(LocalContext))};
|
ALCcontext *Context{static_cast<ALCcontext*>(altss_get(LocalContext))};
|
||||||
if(!Context) Context = ATOMIC_LOAD_SEQ(&GlobalContext);
|
if(!Context) Context = GlobalContext.load();
|
||||||
return Context;
|
return Context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3951,7 +3921,7 @@ ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
|
|||||||
return ALC_FALSE;
|
return ALC_FALSE;
|
||||||
}
|
}
|
||||||
/* context's reference count is already incremented */
|
/* context's reference count is already incremented */
|
||||||
context = ATOMIC_EXCHANGE_PTR_SEQ(&GlobalContext, context);
|
context = GlobalContext.exchange(context);
|
||||||
if(context) ALCcontext_DecRef(context);
|
if(context) ALCcontext_DecRef(context);
|
||||||
|
|
||||||
if((context=static_cast<ALCcontext*>(altss_get(LocalContext))) != nullptr)
|
if((context=static_cast<ALCcontext*>(altss_get(LocalContext))) != nullptr)
|
||||||
@ -4206,7 +4176,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
|
|||||||
*/
|
*/
|
||||||
ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
|
ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
|
||||||
{
|
{
|
||||||
LockLists();
|
std::unique_lock<std::recursive_mutex> listlock{ListLock};
|
||||||
ALCdevice *iter{DeviceList.load()};
|
ALCdevice *iter{DeviceList.load()};
|
||||||
do {
|
do {
|
||||||
if(iter == device)
|
if(iter == device)
|
||||||
@ -4216,14 +4186,13 @@ ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
|
|||||||
if(!iter || iter->Type == Capture)
|
if(!iter || iter->Type == Capture)
|
||||||
{
|
{
|
||||||
alcSetError(iter, ALC_INVALID_DEVICE);
|
alcSetError(iter, ALC_INVALID_DEVICE);
|
||||||
UnlockLists();
|
|
||||||
return ALC_FALSE;
|
return ALC_FALSE;
|
||||||
}
|
}
|
||||||
almtx_lock(&device->BackendLock);
|
almtx_lock(&device->BackendLock);
|
||||||
|
|
||||||
ALCdevice *origdev{device};
|
ALCdevice *origdev{device};
|
||||||
ALCdevice *nextdev{ATOMIC_LOAD(&device->next, almemory_order_relaxed)};
|
ALCdevice *nextdev{ATOMIC_LOAD(&device->next, almemory_order_relaxed)};
|
||||||
if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList, &origdev, nextdev))
|
if(!DeviceList.compare_exchange_strong(origdev, nextdev))
|
||||||
{
|
{
|
||||||
ALCdevice *list;
|
ALCdevice *list;
|
||||||
do {
|
do {
|
||||||
@ -4231,7 +4200,7 @@ ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
|
|||||||
origdev = device;
|
origdev = device;
|
||||||
} while(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&list->next, &origdev, nextdev));
|
} while(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&list->next, &origdev, nextdev));
|
||||||
}
|
}
|
||||||
UnlockLists();
|
listlock.unlock();
|
||||||
|
|
||||||
ALCcontext *ctx{ATOMIC_LOAD_SEQ(&device->ContextList)};
|
ALCcontext *ctx{ATOMIC_LOAD_SEQ(&device->ContextList)};
|
||||||
while(ctx != nullptr)
|
while(ctx != nullptr)
|
||||||
@ -4339,8 +4308,8 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName,
|
|||||||
|
|
||||||
ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
|
ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
|
||||||
{
|
{
|
||||||
|
std::unique_lock<std::recursive_mutex> listlock{ListLock};
|
||||||
|
|
||||||
LockLists();
|
|
||||||
ALCdevice *iter{DeviceList.load()};
|
ALCdevice *iter{DeviceList.load()};
|
||||||
do {
|
do {
|
||||||
if(iter == device)
|
if(iter == device)
|
||||||
@ -4350,7 +4319,6 @@ ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
|
|||||||
if(!iter || iter->Type != Capture)
|
if(!iter || iter->Type != Capture)
|
||||||
{
|
{
|
||||||
alcSetError(iter, ALC_INVALID_DEVICE);
|
alcSetError(iter, ALC_INVALID_DEVICE);
|
||||||
UnlockLists();
|
|
||||||
return ALC_FALSE;
|
return ALC_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4364,7 +4332,7 @@ ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
|
|||||||
origdev = device;
|
origdev = device;
|
||||||
} while(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&list->next, &origdev, nextdev));
|
} while(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&list->next, &origdev, nextdev));
|
||||||
}
|
}
|
||||||
UnlockLists();
|
listlock.unlock();
|
||||||
|
|
||||||
almtx_lock(&device->BackendLock);
|
almtx_lock(&device->BackendLock);
|
||||||
if((device->Flags&DEVICE_RUNNING))
|
if((device->Flags&DEVICE_RUNNING))
|
||||||
@ -4663,17 +4631,17 @@ ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCi
|
|||||||
{
|
{
|
||||||
ALCenum err;
|
ALCenum err;
|
||||||
|
|
||||||
LockLists();
|
std::unique_lock<std::recursive_mutex> listlock{ListLock};
|
||||||
if(!VerifyDevice(&device) || device->Type == Capture ||
|
if(!VerifyDevice(&device) || device->Type == Capture ||
|
||||||
!ATOMIC_LOAD(&device->Connected, almemory_order_relaxed))
|
!ATOMIC_LOAD(&device->Connected, almemory_order_relaxed))
|
||||||
{
|
{
|
||||||
UnlockLists();
|
listlock.unlock();
|
||||||
alcSetError(device, ALC_INVALID_DEVICE);
|
alcSetError(device, ALC_INVALID_DEVICE);
|
||||||
if(device) ALCdevice_DecRef(device);
|
if(device) ALCdevice_DecRef(device);
|
||||||
return ALC_FALSE;
|
return ALC_FALSE;
|
||||||
}
|
}
|
||||||
almtx_lock(&device->BackendLock);
|
almtx_lock(&device->BackendLock);
|
||||||
UnlockLists();
|
listlock.unlock();
|
||||||
|
|
||||||
err = UpdateDeviceParams(device, attribs);
|
err = UpdateDeviceParams(device, attribs);
|
||||||
almtx_unlock(&device->BackendLock);
|
almtx_unlock(&device->BackendLock);
|
||||||
|
@ -32,6 +32,15 @@
|
|||||||
#include "threads.h"
|
#include "threads.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
#define COUNTOF(x) (sizeof(x) / sizeof(0[x]))
|
||||||
|
#else
|
||||||
|
template<typename T, size_t N>
|
||||||
|
constexpr inline size_t countof(const T(&)[N]) noexcept
|
||||||
|
{ return N; }
|
||||||
|
#define COUNTOF countof
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN64)
|
#if defined(_WIN64)
|
||||||
#define SZFMT "%I64u"
|
#define SZFMT "%I64u"
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
@ -197,8 +206,6 @@ static const union {
|
|||||||
#define IS_LITTLE_ENDIAN (EndianTest.b[0] == 1)
|
#define IS_LITTLE_ENDIAN (EndianTest.b[0] == 1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define COUNTOF(x) (sizeof(x) / sizeof(0[x]))
|
|
||||||
|
|
||||||
|
|
||||||
struct ll_ringbuffer;
|
struct ll_ringbuffer;
|
||||||
struct Hrtf;
|
struct Hrtf;
|
||||||
|
Loading…
Reference in New Issue
Block a user