From d22f557a3bd074ff4ee29128f7d8a3375dece37d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 23 Jan 2021 16:14:58 +0100 Subject: [PATCH] Remove possibility of double-disposal interference --- .../OnlinePlay/OngoingOperationTracker.cs | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/OnlinePlay/OngoingOperationTracker.cs b/osu.Game/Screens/OnlinePlay/OngoingOperationTracker.cs index 5d171e6e43..060f1d7b91 100644 --- a/osu.Game/Screens/OnlinePlay/OngoingOperationTracker.cs +++ b/osu.Game/Screens/OnlinePlay/OngoingOperationTracker.cs @@ -44,7 +44,7 @@ namespace osu.Game.Screens.OnlinePlay leasedInProgress.Value = true; // for extra safety, marshal the end of operation back to the update thread if necessary. - return new InvokeOnDisposal(() => Scheduler.Add(endOperation, false)); + return new OngoingOperation(() => Scheduler.Add(endOperation, false)); } private void endOperation() @@ -60,5 +60,26 @@ namespace osu.Game.Screens.OnlinePlay // clean up the leased reference here so that it doesn't get returned twice. leasedInProgress = null; } + + private class OngoingOperation : InvokeOnDisposal + { + private bool isDisposed; + + public OngoingOperation(Action action) + : base(action) + { + } + + public override void Dispose() + { + // base class does not check disposal state for performance reasons which aren't relevant here. + // track locally, to avoid interfering with other operations in case of a potential double-disposal. + if (isDisposed) + return; + + base.Dispose(); + isDisposed = true; + } + } } }