Notify listener on close

This commit is contained in:
Flamefire committed 2014-05-07 00:38:39 +02:00
1 parent cc08e01590
commit c23eaa0834
2 files changed
+18 -1

No files matched your search

+16 -1
View File
@@ -25,6 +25,8 @@ namespace Vocaluxe.Lib.Sound.Playback
{ {
protected bool _Initialized; protected bool _Initialized;
protected readonly List<IAudioStream> _Streams = new List<IAudioStream>(); protected readonly List<IAudioStream> _Streams = new List<IAudioStream>();
private readonly List<IAudioStream> _StreamsToDelete = new List<IAudioStream>();
private bool _InUpdate;
private int _NextID; private int _NextID;
protected float _GlobalVolume = 1f; protected float _GlobalVolume = 1f;
@@ -92,8 +94,18 @@ namespace Vocaluxe.Lib.Sound.Playback
return; return;
lock (_Streams) lock (_Streams)
{ {
_InUpdate = true;
foreach (IAudioStream stream in _Streams) foreach (IAudioStream stream in _Streams)
stream.Update(); 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) 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);
} }
} }
} }
@@ -205,6 +205,8 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
} }
if (element.TargetState == State.Playing) if (element.TargetState == State.Playing)
element.SetState(State.Paused); //Stop output element.SetState(State.Paused); //Stop output
if (_CloseStreamListener != null)
_CloseStreamListener.OnCloseStream(this);
//Now really close it in the background //Now really close it in the background
var t = new System.Threading.Thread(() => _TerminateStream(element)) {Name = "GSt Terminate"}; var t = new System.Threading.Thread(() => _TerminateStream(element)) {Name = "GSt Terminate"};
t.Start(); t.Start();