From 1c8f9d44df20d21619b1d36cec86e6a44744ef0d Mon Sep 17 00:00:00 2001 From: RoosterDragon Date: Sat, 30 Jul 2016 14:53:33 +0100 Subject: [PATCH] Clean up ALC sound device correctly. ALC is thread-safe, therefore we can clean up from any thread and do not need to marshal to the main game thread. To clean up the device properly, we must first unset and destroy the context before attempting to close the device. --- OpenRA.Platforms.Default/OpenAlSoundEngine.cs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/OpenRA.Platforms.Default/OpenAlSoundEngine.cs b/OpenRA.Platforms.Default/OpenAlSoundEngine.cs index 86791cdf58..55b02f4c61 100644 --- a/OpenRA.Platforms.Default/OpenAlSoundEngine.cs +++ b/OpenRA.Platforms.Default/OpenAlSoundEngine.cs @@ -49,6 +49,7 @@ namespace OpenRA.Platforms.Default readonly Dictionary sourcePool = new Dictionary(); float volume = 1f; IntPtr device; + IntPtr context; static string[] QueryDevices(string label, int type) { @@ -103,10 +104,10 @@ namespace OpenRA.Platforms.Default throw new InvalidOperationException("Can't create OpenAL device"); } - var ctx = ALC10.alcCreateContext(device, null); - if (ctx == IntPtr.Zero) + context = ALC10.alcCreateContext(device, null); + if (context == IntPtr.Zero) throw new InvalidOperationException("Can't create OpenAL context"); - ALC10.alcMakeContextCurrent(ctx); + ALC10.alcMakeContextCurrent(context); for (var i = 0; i < PoolSize; i++) { @@ -303,17 +304,24 @@ namespace OpenRA.Platforms.Default ~OpenAlSoundEngine() { - Game.RunAfterTick(() => Dispose(false)); + Dispose(false); } public void Dispose() { - Game.RunAfterTick(() => Dispose(true)); + Dispose(true); GC.SuppressFinalize(this); } void Dispose(bool disposing) { + if (context != IntPtr.Zero) + { + ALC10.alcMakeContextCurrent(IntPtr.Zero); + ALC10.alcDestroyContext(context); + context = IntPtr.Zero; + } + if (device != IntPtr.Zero) { ALC10.alcCloseDevice(device);