From c23eaa08346dca9b224950c1ef90af2219eb551e Mon Sep 17 00:00:00 2001 From: Flamefire Date: Wed, 7 May 2014 00:38:39 +0200 Subject: [PATCH] Notify listener on close --- Vocaluxe/Lib/Sound/Playback/CPlaybackBase.cs | 17 ++++++++++++++++- .../CGstreamerSharpAudioStream.cs | 2 ++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Vocaluxe/Lib/Sound/Playback/CPlaybackBase.cs b/Vocaluxe/Lib/Sound/Playback/CPlaybackBase.cs index d94e3780..05f5a35f 100644 --- a/Vocaluxe/Lib/Sound/Playback/CPlaybackBase.cs +++ b/Vocaluxe/Lib/Sound/Playback/CPlaybackBase.cs @@ -25,6 +25,8 @@ namespace Vocaluxe.Lib.Sound.Playback { protected bool _Initialized; protected readonly List _Streams = new List(); + private readonly List _StreamsToDelete = new List(); + private bool _InUpdate; private int _NextID; protected float _GlobalVolume = 1f; @@ -92,8 +94,18 @@ namespace Vocaluxe.Lib.Sound.Playback return; lock (_Streams) { + _InUpdate = true; foreach (IAudioStream stream in _Streams) stream.Update(); + //This is required because a stream may call the close listener from inside the update method + //lock() only protects from different threads not from the same, so we use StreamsToDelete to not modify _Streams while iterating it + _InUpdate = false; + if (_StreamsToDelete.Count > 0) + { + foreach (IAudioStream stream in _StreamsToDelete) + _Streams.Remove(stream); + _StreamsToDelete.Clear(); + } } } @@ -301,7 +313,10 @@ namespace Vocaluxe.Lib.Sound.Playback { lock (_Streams) { - _Streams.Remove(stream); + if (_InUpdate) //This is only possible if this is called from inside the update method + _StreamsToDelete.Add(stream); + else + _Streams.Remove(stream); } } } diff --git a/Vocaluxe/Lib/Sound/Playback/GstreamerSharp/CGstreamerSharpAudioStream.cs b/Vocaluxe/Lib/Sound/Playback/GstreamerSharp/CGstreamerSharpAudioStream.cs index 994353ef..36b6a7d8 100644 --- a/Vocaluxe/Lib/Sound/Playback/GstreamerSharp/CGstreamerSharpAudioStream.cs +++ b/Vocaluxe/Lib/Sound/Playback/GstreamerSharp/CGstreamerSharpAudioStream.cs @@ -205,6 +205,8 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp } if (element.TargetState == State.Playing) element.SetState(State.Paused); //Stop output + if (_CloseStreamListener != null) + _CloseStreamListener.OnCloseStream(this); //Now really close it in the background var t = new System.Threading.Thread(() => _TerminateStream(element)) {Name = "GSt Terminate"}; t.Start();