From 818fac6ac8effd7f273c634fb1dd021550b7b4ff Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 15 Oct 2021 13:58:14 +0900 Subject: [PATCH] Make realm a non-drawable component to better order disposal Until now, the `RealmContextFactory` would be disposed as part of the drawable hierarchy. This is too early, as it may be being used by higher level components (like `ConfigManager`s, see #15115) that perform final operations after the drawables have been disposed. Seems to make sense moving this out of the drawable hierarchy and in line with how we were doing things with EF. --- osu.Game/Database/RealmContextFactory.cs | 24 +++++++++++++----------- osu.Game/OsuGameBase.cs | 3 +-- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/osu.Game/Database/RealmContextFactory.cs b/osu.Game/Database/RealmContextFactory.cs index c3810eb441..82d51e365e 100644 --- a/osu.Game/Database/RealmContextFactory.cs +++ b/osu.Game/Database/RealmContextFactory.cs @@ -5,7 +5,6 @@ using System; using System.Threading; using osu.Framework.Allocation; using osu.Framework.Development; -using osu.Framework.Graphics; using osu.Framework.Logging; using osu.Framework.Platform; using osu.Framework.Statistics; @@ -18,7 +17,7 @@ namespace osu.Game.Database /// /// A factory which provides both the main (update thread bound) realm context and creates contexts for async usage. /// - public class RealmContextFactory : Component, IRealmFactory + public class RealmContextFactory : IDisposable, IRealmFactory { private readonly Storage storage; @@ -79,10 +78,11 @@ namespace osu.Game.Database /// public bool Compact() => Realm.Compact(getConfiguration()); - protected override void Update() + /// + /// Perform a blocking refresh on the main realm context. + /// + public void Refresh() { - base.Update(); - lock (contextLock) { if (context?.Refresh() == true) @@ -92,7 +92,7 @@ namespace osu.Game.Database public Realm CreateContext() { - if (IsDisposed) + if (isDisposed) throw new ObjectDisposedException(nameof(RealmContextFactory)); try @@ -132,7 +132,7 @@ namespace osu.Game.Database /// An which should be disposed to end the blocking section. public IDisposable BlockAllOperations() { - if (IsDisposed) + if (isDisposed) throw new ObjectDisposedException(nameof(RealmContextFactory)); if (!ThreadSafety.IsUpdateThread) @@ -176,21 +176,23 @@ namespace osu.Game.Database }); } - protected override void Dispose(bool isDisposing) + private bool isDisposed; + + public void Dispose() { lock (contextLock) { context?.Dispose(); } - if (!IsDisposed) + if (!isDisposed) { // intentionally block context creation indefinitely. this ensures that nothing can start consuming a new context after disposal. contextCreationLock.Wait(); contextCreationLock.Dispose(); - } - base.Dispose(isDisposing); + isDisposed = true; + } } } } diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 09eb482d16..f6ec22a536 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -187,8 +187,6 @@ namespace osu.Game dependencies.Cache(realmFactory = new RealmContextFactory(Storage, "client")); - AddInternal(realmFactory); - dependencies.CacheAs(Storage); var largeStore = new LargeTextureStore(Host.CreateTextureLoaderStore(new NamespacedResourceStore(Resources, @"Textures"))); @@ -529,6 +527,7 @@ namespace osu.Game LocalConfig?.Dispose(); contextFactory?.FlushConnections(); + realmFactory?.Dispose(); } } }