From 8fe63689a420010c3498ff235edf3cfd99a78b0a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 5 Nov 2016 18:16:15 +0900 Subject: [PATCH] Fix thread safety issue when accessing files in beatmap (zip) files. --- .../Tests/TestCasePlayer.cs | 9 +++----- osu.Game/Beatmaps/WorkingBeatmap.cs | 23 +++++++++++++------ osu.Game/Database/BeatmapDatabase.cs | 4 +--- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs b/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs index a3ae103f28..1d292442e6 100644 --- a/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs +++ b/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs @@ -46,13 +46,10 @@ namespace osu.Desktop.VisualTests.Tests Add(new Player { - Beatmap = new WorkingBeatmap + Beatmap = new WorkingBeatmap(new Beatmap { - Beatmap = new Beatmap - { - HitObjects = objects - } - } + HitObjects = objects + }) }); } diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 4deed53465..a2a0a27e02 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -12,9 +12,12 @@ namespace osu.Game.Beatmaps { public class WorkingBeatmap : IDisposable { - public BeatmapInfo BeatmapInfo; + public readonly BeatmapInfo BeatmapInfo; - public readonly ArchiveReader Reader; + public readonly BeatmapSetInfo BeatmapSetInfo; + private readonly BeatmapDatabase database; + + private ArchiveReader reader => database.GetReader(BeatmapSetInfo); private Beatmap beatmap; public Beatmap Beatmap @@ -25,7 +28,7 @@ namespace osu.Game.Beatmaps try { - using (var stream = new StreamReader(Reader.ReadFile(BeatmapInfo.Path))) + using (var stream = new StreamReader(reader.ReadFile(BeatmapInfo.Path))) beatmap = BeatmapDecoder.GetDecoder(stream)?.Decode(stream); } catch { } @@ -44,7 +47,7 @@ namespace osu.Game.Beatmaps try { - var trackData = Reader.ReadFile(BeatmapInfo.Metadata.AudioFile); + var trackData = reader.ReadFile(BeatmapInfo.Metadata.AudioFile); if (trackData != null) track = new AudioTrackBass(trackData); } @@ -55,10 +58,16 @@ namespace osu.Game.Beatmaps set { track = value; } } - public WorkingBeatmap(BeatmapInfo beatmapInfo = null, ArchiveReader reader = null) + public WorkingBeatmap(Beatmap beatmap) + { + this.beatmap = beatmap; + } + + public WorkingBeatmap(BeatmapInfo beatmapInfo, BeatmapSetInfo beatmapSetInfo, BeatmapDatabase database) { this.BeatmapInfo = beatmapInfo; - Reader = reader; + this.BeatmapSetInfo = beatmapSetInfo; + this.database = database; } private bool isDisposed; @@ -68,7 +77,7 @@ namespace osu.Game.Beatmaps if (!isDisposed) { track?.Dispose(); - Reader?.Dispose(); + reader?.Dispose(); isDisposed = true; } } diff --git a/osu.Game/Database/BeatmapDatabase.cs b/osu.Game/Database/BeatmapDatabase.cs index bb98daf6bc..06007dba9c 100644 --- a/osu.Game/Database/BeatmapDatabase.cs +++ b/osu.Game/Database/BeatmapDatabase.cs @@ -149,12 +149,10 @@ namespace osu.Game.Database if (beatmapSetInfo == null) throw new InvalidOperationException($@"Beatmap set {beatmapInfo.BeatmapSetID} is not in the local database."); - var reader = GetReader(beatmapSetInfo); - if (beatmapInfo.Metadata == null) beatmapInfo.Metadata = beatmapSetInfo.Metadata; - var working = new WorkingBeatmap(beatmapInfo, reader); + var working = new WorkingBeatmap(beatmapInfo, beatmapSetInfo, this); previous?.TransferTo(working);