Skip to content
This repository has been archived by the owner on Jan 21, 2022. It is now read-only.

Commit

Permalink
Multiplayer Exceptions (#474)
Browse files Browse the repository at this point in the history
Lock access to "LoadedMedias", RegisterEvents and "allInstances" in order to make access to those resources, thread safe.

Fixes #430 and #464
  • Loading branch information
dilandau2001 authored and jeremyVignelles committed Oct 24, 2018
1 parent b1b81bb commit edf4cd8
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 27 deletions.
27 changes: 16 additions & 11 deletions src/Vlc.DotNet.Core.Interops/VlcMediaInstance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,22 @@ namespace Vlc.DotNet.Core.Interops
public sealed class VlcMediaInstance : InteropObjectInstance
{
private readonly VlcManager myManager;

private static List<VlcMediaInstance> allInstances = new List<VlcMediaInstance>();
private static readonly Dictionary<IntPtr, VlcMediaInstance> AllInstances = new Dictionary<IntPtr, VlcMediaInstance>();

public static VlcMediaInstance New(VlcManager manager, IntPtr pointer)
{
var instance = allInstances.Find(delegate(VlcMediaInstance i)
{
return i == pointer;
});
if (null == instance)
lock (AllInstances)
{
instance = new VlcMediaInstance(manager, pointer);
allInstances.Add(instance);
AllInstances.TryGetValue(pointer, out var instance);

if (null == instance)
{
instance = new VlcMediaInstance(manager, pointer);
AllInstances.Add(pointer, instance);
}

return instance;
}
return instance;
}

private VlcMediaInstance(VlcManager manager, IntPtr pointer) : base(pointer)
Expand All @@ -31,7 +32,11 @@ private VlcMediaInstance(VlcManager manager, IntPtr pointer) : base(pointer)

protected override void Dispose(bool disposing)
{
allInstances.Remove(this);
lock (AllInstances)
{
AllInstances.Remove(this);
}

if (Pointer != IntPtr.Zero)
myManager.ReleaseMedia(this);
base.Dispose(disposing);
Expand Down
38 changes: 29 additions & 9 deletions src/Vlc.DotNet.Core/VlcMedia/VlcMedia.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ namespace Vlc.DotNet.Core
public sealed partial class VlcMedia : IDisposable
{
private readonly VlcMediaPlayer myVlcMediaPlayer;

internal static Dictionary<VlcMediaPlayer, List<VlcMedia>> LoadedMedias { get; private set; }
private static Dictionary<VlcMediaPlayer, List<VlcMedia>> LoadedMedias { get; }

static VlcMedia()
{
{
LoadedMedias = new Dictionary<VlcMediaPlayer, List<VlcMedia>>();
}

Expand Down Expand Up @@ -55,12 +54,18 @@ internal VlcMedia(VlcMediaPlayer player, Stream stream, params string[] options)

internal VlcMedia(VlcMediaPlayer player, VlcMediaInstance mediaInstance)
{
if(!LoadedMedias.ContainsKey(player))
LoadedMedias[player] = new List<VlcMedia>();
LoadedMedias[player].Add(this);
MediaInstance = mediaInstance;
myVlcMediaPlayer = player;
RegisterEvents();
lock(LoadedMedias)
{
if(!LoadedMedias.ContainsKey(player))
{
LoadedMedias[player] = new List<VlcMedia>();
}

LoadedMedias[player].Add(this);
MediaInstance = mediaInstance;
myVlcMediaPlayer = player;
RegisterEvents();
}
}

internal VlcMediaInstance MediaInstance { get; private set; }
Expand Down Expand Up @@ -149,5 +154,20 @@ private void UnregisterEvents()
myVlcMediaPlayer.Manager.DetachEvent(eventManager, EventTypes.MediaSubItemTreeAdded, myOnMediaSubItemTreeAddedInternalEventCallback);
eventManager.Dispose();
}

internal static void RemoveAll(VlcMediaPlayer mediaToRemove)
{
lock(LoadedMedias)
{
if (!LoadedMedias.ContainsKey(mediaToRemove)) return;

foreach (var loadedMedia in LoadedMedias[mediaToRemove])
{
loadedMedia.Dispose();
}

LoadedMedias.Remove(mediaToRemove);
}
}
}
}
8 changes: 1 addition & 7 deletions src/Vlc.DotNet.Core/VlcMediaPlayer/VlcMediaPlayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,7 @@ private void Dispose(bool disposing)
if (IsPlaying())
Stop();

if (VlcMedia.LoadedMedias.ContainsKey(this))
foreach (var loadedMedia in VlcMedia.LoadedMedias[this])
{
loadedMedia.Dispose();
}
VlcMedia.LoadedMedias.Remove(this);

VlcMedia.RemoveAll(this);
myMediaPlayerInstance.Dispose();
Manager.Dispose();
}
Expand Down

0 comments on commit edf4cd8

Please sign in to comment.