Move the device lock into the backend function table
For backend-specific implementations: this should hold the audio mixer loop for playback devices, and provide recursive mutex behavior.
This commit is contained in:
@@ -43,7 +43,7 @@
|
||||
/************************************************
|
||||
* Backends
|
||||
************************************************/
|
||||
#define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
|
||||
#define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
|
||||
static struct BackendInfo BackendList[] = {
|
||||
#ifdef HAVE_PULSEAUDIO
|
||||
{ "pulse", alc_pulse_init, alc_pulse_deinit, alc_pulse_probe, EmptyFuncs },
|
||||
@@ -1259,6 +1259,15 @@ static ALCboolean IsValidALCChannels(ALCenum channels)
|
||||
* Miscellaneous ALC helpers
|
||||
************************************************/
|
||||
|
||||
void ALCdevice_LockDefault(ALCdevice *device)
|
||||
{
|
||||
EnterCriticalSection(&device->Mutex);
|
||||
}
|
||||
void ALCdevice_UnlockDefault(ALCdevice *device)
|
||||
{
|
||||
LeaveCriticalSection(&device->Mutex);
|
||||
}
|
||||
|
||||
/* SetDefaultWFXChannelOrder
|
||||
*
|
||||
* Sets the default channel order used by WaveFormatEx.
|
||||
@@ -1609,7 +1618,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
|
||||
device->Flags |= DEVICE_WIDE_STEREO;
|
||||
|
||||
oldMode = SetMixerFPUMode();
|
||||
LockDevice(device);
|
||||
ALCdevice_Lock(device);
|
||||
context = device->ContextList;
|
||||
while(context)
|
||||
{
|
||||
@@ -1624,7 +1633,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
|
||||
if(ALeffectState_DeviceUpdate(slot->EffectState, device) == AL_FALSE)
|
||||
{
|
||||
UnlockUIntMapRead(&context->EffectSlotMap);
|
||||
UnlockDevice(device);
|
||||
ALCdevice_Unlock(device);
|
||||
RestoreFPUMode(oldMode);
|
||||
return ALC_INVALID_DEVICE;
|
||||
}
|
||||
@@ -1660,14 +1669,14 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
|
||||
|
||||
if(ALeffectState_DeviceUpdate(slot->EffectState, device) == AL_FALSE)
|
||||
{
|
||||
UnlockDevice(device);
|
||||
ALCdevice_Unlock(device);
|
||||
RestoreFPUMode(oldMode);
|
||||
return ALC_INVALID_DEVICE;
|
||||
}
|
||||
slot->NeedsUpdate = AL_FALSE;
|
||||
ALeffectState_Update(slot->EffectState, device, slot);
|
||||
}
|
||||
UnlockDevice(device);
|
||||
ALCdevice_Unlock(device);
|
||||
RestoreFPUMode(oldMode);
|
||||
|
||||
if(ALCdevice_StartPlayback(device) == ALC_FALSE)
|
||||
@@ -1876,7 +1885,7 @@ static void ReleaseContext(ALCcontext *context, ALCdevice *device)
|
||||
if(CompExchangePtr((XchgPtr*)&GlobalContext, context, NULL))
|
||||
ALCcontext_DecRef(context);
|
||||
|
||||
LockDevice(device);
|
||||
ALCdevice_Lock(device);
|
||||
tmp_ctx = &device->ContextList;
|
||||
while(*tmp_ctx)
|
||||
{
|
||||
@@ -1884,7 +1893,7 @@ static void ReleaseContext(ALCcontext *context, ALCdevice *device)
|
||||
break;
|
||||
tmp_ctx = &(*tmp_ctx)->next;
|
||||
}
|
||||
UnlockDevice(device);
|
||||
ALCdevice_Unlock(device);
|
||||
|
||||
ALCcontext_DecRef(context);
|
||||
}
|
||||
|
||||
@@ -921,7 +921,7 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
|
||||
SamplesToDo = minu(size, BUFFERSIZE);
|
||||
memset(device->DryBuffer, 0, SamplesToDo*MaxChannels*sizeof(ALfloat));
|
||||
|
||||
LockDevice(device);
|
||||
ALCdevice_Lock(device);
|
||||
ctx = device->ContextList;
|
||||
while(ctx)
|
||||
{
|
||||
@@ -999,7 +999,7 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
|
||||
for(i = 0;i < SamplesToDo;i++)
|
||||
(*slot)->WetBuffer[i] = 0.0f;
|
||||
}
|
||||
UnlockDevice(device);
|
||||
ALCdevice_Unlock(device);
|
||||
|
||||
/* Click-removal. Could do better; this only really handles immediate
|
||||
* changes between updates where a predictive sample could be
|
||||
@@ -1092,7 +1092,7 @@ ALvoid aluHandleDisconnect(ALCdevice *device)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
LockDevice(device);
|
||||
ALCdevice_Lock(device);
|
||||
device->Connected = ALC_FALSE;
|
||||
|
||||
Context = device->ContextList;
|
||||
@@ -1117,5 +1117,5 @@ ALvoid aluHandleDisconnect(ALCdevice *device)
|
||||
|
||||
Context = Context->next;
|
||||
}
|
||||
UnlockDevice(device);
|
||||
ALCdevice_Unlock(device);
|
||||
}
|
||||
|
||||
@@ -1254,6 +1254,8 @@ static const BackendFuncs alsa_funcs = {
|
||||
alsa_stop_capture,
|
||||
alsa_capture_samples,
|
||||
alsa_available_samples,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
alsa_get_latency
|
||||
};
|
||||
|
||||
|
||||
@@ -682,6 +682,8 @@ static const BackendFuncs ca_funcs = {
|
||||
ca_stop_capture,
|
||||
ca_capture_samples,
|
||||
ca_available_samples,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
ca_get_latency
|
||||
};
|
||||
|
||||
|
||||
@@ -954,6 +954,8 @@ static const BackendFuncs DSoundFuncs = {
|
||||
DSoundStopCapture,
|
||||
DSoundCaptureSamples,
|
||||
DSoundAvailableSamples,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
DSoundGetLatency
|
||||
};
|
||||
|
||||
|
||||
@@ -74,6 +74,8 @@ static const BackendFuncs loopback_funcs = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
loopback_get_latency
|
||||
};
|
||||
|
||||
|
||||
@@ -956,6 +956,8 @@ static const BackendFuncs MMDevApiFuncs = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
MMDevApiGetLatency
|
||||
};
|
||||
|
||||
|
||||
@@ -149,6 +149,8 @@ static const BackendFuncs null_funcs = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
null_get_latency
|
||||
};
|
||||
|
||||
|
||||
@@ -420,6 +420,8 @@ static const BackendFuncs opensl_funcs = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
opensl_get_latency
|
||||
};
|
||||
|
||||
|
||||
@@ -495,6 +495,8 @@ static const BackendFuncs oss_funcs = {
|
||||
oss_stop_capture,
|
||||
oss_capture_samples,
|
||||
oss_available_samples,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
oss_get_latency
|
||||
};
|
||||
|
||||
|
||||
@@ -438,6 +438,8 @@ static const BackendFuncs pa_funcs = {
|
||||
pa_stop_capture,
|
||||
pa_capture_samples,
|
||||
pa_available_samples,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
pa_get_latency
|
||||
};
|
||||
|
||||
|
||||
@@ -1407,6 +1407,8 @@ static const BackendFuncs pulse_funcs = {
|
||||
pulse_stop_capture,
|
||||
pulse_capture_samples,
|
||||
pulse_available_samples,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
pulse_get_latency
|
||||
};
|
||||
|
||||
|
||||
@@ -271,6 +271,8 @@ static const BackendFuncs sndio_funcs = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
sndio_get_latency
|
||||
};
|
||||
|
||||
|
||||
@@ -255,6 +255,8 @@ static const BackendFuncs solaris_funcs = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
solaris_get_latency
|
||||
};
|
||||
|
||||
|
||||
@@ -342,6 +342,8 @@ static const BackendFuncs wave_funcs = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
wave_get_latency
|
||||
};
|
||||
|
||||
|
||||
@@ -724,6 +724,8 @@ static const BackendFuncs WinMMFuncs = {
|
||||
WinMMStopCapture,
|
||||
WinMMCaptureSamples,
|
||||
WinMMAvailableSamples,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
WinMMGetLatency
|
||||
};
|
||||
|
||||
|
||||
@@ -446,6 +446,9 @@ typedef struct {
|
||||
ALCenum (*CaptureSamples)(ALCdevice*, void*, ALCuint);
|
||||
ALCuint (*AvailableSamples)(ALCdevice*);
|
||||
|
||||
void (*Lock)(ALCdevice*);
|
||||
void (*Unlock)(ALCdevice*);
|
||||
|
||||
ALint64 (*GetLatency)(ALCdevice*);
|
||||
} BackendFuncs;
|
||||
|
||||
@@ -632,6 +635,8 @@ struct ALCdevice_struct
|
||||
#define ALCdevice_StopCapture(a) ((a)->Funcs->StopCapture((a)))
|
||||
#define ALCdevice_CaptureSamples(a,b,c) ((a)->Funcs->CaptureSamples((a), (b), (c)))
|
||||
#define ALCdevice_AvailableSamples(a) ((a)->Funcs->AvailableSamples((a)))
|
||||
#define ALCdevice_Lock(a) ((a)->Funcs->Lock((a)))
|
||||
#define ALCdevice_Unlock(a) ((a)->Funcs->Unlock((a)))
|
||||
#define ALCdevice_GetLatency(a) ((a)->Funcs->GetLatency((a)))
|
||||
|
||||
// Frequency was requested by the app or config file
|
||||
@@ -703,15 +708,13 @@ void ALCcontext_DecRef(ALCcontext *context);
|
||||
void AppendAllDevicesList(const ALCchar *name);
|
||||
void AppendCaptureDeviceList(const ALCchar *name);
|
||||
|
||||
static __inline void LockDevice(ALCdevice *device)
|
||||
{ EnterCriticalSection(&device->Mutex); }
|
||||
static __inline void UnlockDevice(ALCdevice *device)
|
||||
{ LeaveCriticalSection(&device->Mutex); }
|
||||
void ALCdevice_LockDefault(ALCdevice *device);
|
||||
void ALCdevice_UnlockDefault(ALCdevice *device);
|
||||
|
||||
static __inline void LockContext(ALCcontext *context)
|
||||
{ LockDevice(context->Device); }
|
||||
{ ALCdevice_Lock(context->Device); }
|
||||
static __inline void UnlockContext(ALCcontext *context)
|
||||
{ UnlockDevice(context->Device); }
|
||||
{ ALCdevice_Unlock(context->Device); }
|
||||
|
||||
|
||||
void *al_malloc(size_t alignment, size_t size);
|
||||
|
||||
@@ -487,7 +487,7 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e
|
||||
ALeffectState *State = NULL;
|
||||
ALenum err = AL_NO_ERROR;
|
||||
|
||||
LockDevice(Device);
|
||||
ALCdevice_Lock(Device);
|
||||
if(newtype == AL_EFFECT_NULL && EffectSlot->effect.type != AL_EFFECT_NULL)
|
||||
{
|
||||
State = NoneCreate();
|
||||
@@ -522,7 +522,7 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e
|
||||
|
||||
if(err != AL_NO_ERROR)
|
||||
{
|
||||
UnlockDevice(Device);
|
||||
ALCdevice_Unlock(Device);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -534,7 +534,7 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e
|
||||
if(ALeffectState_DeviceUpdate(State, Device) == AL_FALSE)
|
||||
{
|
||||
RestoreFPUMode(oldMode);
|
||||
UnlockDevice(Device);
|
||||
ALCdevice_Unlock(Device);
|
||||
ALeffectState_Destroy(State);
|
||||
return AL_OUT_OF_MEMORY;
|
||||
}
|
||||
@@ -549,7 +549,7 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e
|
||||
* be called. */
|
||||
EffectSlot->NeedsUpdate = AL_FALSE;
|
||||
ALeffectState_Update(EffectSlot->EffectState, Device, EffectSlot);
|
||||
UnlockDevice(Device);
|
||||
ALCdevice_Unlock(Device);
|
||||
|
||||
RestoreFPUMode(oldMode);
|
||||
|
||||
@@ -562,7 +562,7 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e
|
||||
memset(&EffectSlot->effect, 0, sizeof(EffectSlot->effect));
|
||||
else
|
||||
memcpy(&EffectSlot->effect, effect, sizeof(*effect));
|
||||
UnlockDevice(Device);
|
||||
ALCdevice_Unlock(Device);
|
||||
EffectSlot->NeedsUpdate = AL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user