aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/alc.cpp
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2018-11-28 12:24:12 -0800
committerChris Robinson <[email protected]>2018-11-28 12:24:12 -0800
commit598851fed7dfdd787de3487002afb13ed6e9dc82 (patch)
tree458faab41979dde680ef78969add47a118c18f7c /Alc/alc.cpp
parent16aa3ab1962a4f77e79521ee344077c37e24bf4f (diff)
Attempt to reconnect lost devices with alcResetDeviceSOFT
Be aware there's currently possible race conditions with PulseAudio's callbacks (the state callbacks need to be cleared while not playing). Also paused sources will assert/crash if attempted to play again without being explicitly stopped or rewound first. Both of these will eventually be fixed (though a paused source's offset will be lost regardless).
Diffstat (limited to 'Alc/alc.cpp')
-rw-r--r--Alc/alc.cpp26
1 files changed, 19 insertions, 7 deletions
diff --git a/Alc/alc.cpp b/Alc/alc.cpp
index 6c522462..8a4407aa 100644
--- a/Alc/alc.cpp
+++ b/Alc/alc.cpp
@@ -3102,7 +3102,9 @@ static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALC
return 1;
case ALC_CONNECTED:
- values[0] = device->Connected.load(std::memory_order_acquire);
+ { std::lock_guard<std::mutex> _{device->BackendLock};
+ values[0] = device->Connected.load(std::memory_order_acquire);
+ }
return 1;
default:
@@ -3289,7 +3291,9 @@ static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALC
return 1;
case ALC_CONNECTED:
- values[0] = device->Connected.load(std::memory_order_acquire);
+ { std::lock_guard<std::mutex> _{device->BackendLock};
+ values[0] = device->Connected.load(std::memory_order_acquire);
+ }
return 1;
case ALC_HRTF_SOFT:
@@ -3583,11 +3587,6 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin
if((err=UpdateDeviceParams(dev.get(), attrList)) != ALC_NO_ERROR)
{
- backlock.unlock();
-
- delete ALContext;
- ALContext = nullptr;
-
alcSetError(dev.get(), err);
if(err == ALC_INVALID_DEVICE)
{
@@ -3595,6 +3594,11 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin
aluHandleDisconnect(dev.get(), "Device update failure");
V0(dev->Backend,unlock)();
}
+ backlock.unlock();
+
+ delete ALContext;
+ ALContext = nullptr;
+
return nullptr;
}
AllocateVoices(ALContext, 256, dev->NumAuxSends);
@@ -4385,6 +4389,14 @@ ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCi
std::lock_guard<std::mutex> _{dev->BackendLock};
listlock.unlock();
+ /* Force the backend to stop mixing first since we're resetting. Also reset
+ * the connected state so lost devices can attempt recover.
+ */
+ if((dev->Flags&DEVICE_RUNNING))
+ V0(dev->Backend,stop)();
+ dev->Flags &= ~DEVICE_RUNNING;
+ device->Connected.store(AL_TRUE);
+
ALCenum err{UpdateDeviceParams(dev.get(), attribs)};
if(LIKELY(err == ALC_NO_ERROR)) return ALC_TRUE;