From 951b95ff7838ff7dfde8f6fc196be7118088626f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 28 Feb 2019 17:17:51 +0900 Subject: [PATCH] Fix potential race condition --- osu.Game/OsuGame.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 3c6922d8a1..f7dbbfd152 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using osu.Framework.Configuration; using osu.Framework.Screens; using osu.Game.Configuration; @@ -628,10 +629,24 @@ namespace osu.Game { Logger.Log($"Loading {d}...", level: LogLevel.Debug); + // Since this is running in a separate thread, it is possible for OsuGame to be disposed after LoadComponentAsync has been called + // throwing an exception. To avoid this, the call is scheduled on the update thread, which does not run if IsDisposed = true + Task task = null; + var del = new ScheduledDelegate(() => task = LoadComponentAsync(d, add)); + Scheduler.Add(del); + + // The delegate won't complete if OsuGame has been disposed in the meantime + while (!IsDisposed && !del.Completed) + await Task.Delay(10); + + // Either we're disposed or the load process has started successfully if (IsDisposed) return; - await LoadComponentAsync(d, add); + Debug.Assert(task != null); + + await task; + Logger.Log($"Loaded {d}!", level: LogLevel.Debug); } catch (OperationCanceledException)