Merge pull request #18849 from peppy/fix-another-test-deadlock

Fix test deadlock due to TPL threadpool saturation
This commit is contained in:
Dan Balasescu 2022-06-26 17:37:15 +09:00 committed by GitHub
commit 0bd230217b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -4,14 +4,14 @@
#nullable disable #nullable disable
using System; using System;
using System.Threading.Tasks;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Game.Database; using osu.Framework.Logging;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Database;
using osu.Game.Online.API; using osu.Game.Online.API;
using osu.Game.Online.Rooms; using osu.Game.Online.Rooms;
using osu.Game.Screens.OnlinePlay; using osu.Game.Screens.OnlinePlay;
@ -72,22 +72,18 @@ namespace osu.Game.Tests.Visual.OnlinePlay
((DummyAPIAccess)API).HandleRequest = request => ((DummyAPIAccess)API).HandleRequest = request =>
{ {
TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>(); try
// Because some of the handlers use realm, we need to ensure the game is still alive when firing.
// If we don't, a stray `PerformAsync` could hit an `ObjectDisposedException` if running too late.
Scheduler.Add(() =>
{ {
bool result = handler.HandleRequest(request, API.LocalUser.Value, beatmapManager); return handler.HandleRequest(request, API.LocalUser.Value, beatmapManager);
tcs.SetResult(result); }
}, false); catch (ObjectDisposedException)
{
#pragma warning disable RS0030 // These requests can be fired asynchronously, but potentially arrive after game components
// We can't GetResultSafely() here (will fail with "Can't use GetResultSafely from inside an async operation."), but Wait is safe enough due to // have been disposed (ie. realm in BeatmapManager).
// the task being a TaskCompletionSource. // This only happens in tests and it's easiest to ignore them for now.
// Importantly, this doesn't deadlock because of the scheduler call above running inline where feasible (see the `false` argument). Logger.Log($"Handled {nameof(ObjectDisposedException)} in test request handling");
return tcs.Task.Result; return true;
#pragma warning restore RS0030 }
}; };
}); });