From d5dccbc3d783c5cc5cb7389fcc970a175ea133e6 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 2 Dec 2020 19:02:49 +0900 Subject: [PATCH] Fix spectator not being thread-safe --- .../Spectator/SpectatorStreamingClient.cs | 33 ++++++++++++++----- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/osu.Game/Online/Spectator/SpectatorStreamingClient.cs b/osu.Game/Online/Spectator/SpectatorStreamingClient.cs index 9ba81720d8..08b524087a 100644 --- a/osu.Game/Online/Spectator/SpectatorStreamingClient.cs +++ b/osu.Game/Online/Spectator/SpectatorStreamingClient.cs @@ -36,6 +36,8 @@ namespace osu.Game.Online.Spectator private readonly List watchingUsers = new List(); + private readonly object userLock = new object(); + public IBindableList PlayingUsers => playingUsers; private readonly BindableList playingUsers = new BindableList(); @@ -144,12 +146,19 @@ namespace osu.Game.Online.Spectator await connection.StartAsync(); Logger.Log("Spectator client connected!", LoggingTarget.Network); + // get all the users that were previously being watched + int[] users; + + lock (userLock) + { + users = watchingUsers.ToArray(); + watchingUsers.Clear(); + } + // success isConnected = true; // resubscribe to watched users - var users = watchingUsers.ToArray(); - watchingUsers.Clear(); foreach (var userId in users) WatchUser(userId); @@ -238,21 +247,29 @@ namespace osu.Game.Online.Spectator public virtual void WatchUser(int userId) { - if (watchingUsers.Contains(userId)) - return; + lock (userLock) + { + if (watchingUsers.Contains(userId)) + return; - watchingUsers.Add(userId); + watchingUsers.Add(userId); - if (!isConnected) return; + if (!isConnected) + return; + } connection.SendAsync(nameof(ISpectatorServer.StartWatchingUser), userId); } public void StopWatchingUser(int userId) { - watchingUsers.Remove(userId); + lock (userLock) + { + watchingUsers.Remove(userId); - if (!isConnected) return; + if (!isConnected) + return; + } connection.SendAsync(nameof(ISpectatorServer.EndWatchingUser), userId); }