From 8557530cd5e744110b13a167ad30306c7224823e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 1 Oct 2021 03:45:00 +0900 Subject: [PATCH 1/2] Add back main context locking --- osu.Game/Database/RealmContextFactory.cs | 30 ++++++++++++++++-------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/osu.Game/Database/RealmContextFactory.cs b/osu.Game/Database/RealmContextFactory.cs index c51ac095bb..0e18b68276 100644 --- a/osu.Game/Database/RealmContextFactory.cs +++ b/osu.Game/Database/RealmContextFactory.cs @@ -37,6 +37,7 @@ namespace osu.Game.Database private static readonly GlobalStatistic refreshes = GlobalStatistics.Get("Realm", "Dirty Refreshes"); private static readonly GlobalStatistic contexts_created = GlobalStatistics.Get("Realm", "Contexts (Created)"); + private readonly object contextLock = new object(); private Realm? context; public Realm Context @@ -46,14 +47,17 @@ namespace osu.Game.Database if (!ThreadSafety.IsUpdateThread) throw new InvalidOperationException($"Use {nameof(CreateContext)} when performing realm operations from a non-update thread"); - if (context == null) + lock (contextLock) { - context = createContext(); - Logger.Log($"Opened realm \"{context.Config.DatabasePath}\" at version {context.Config.SchemaVersion}"); - } + if (context == null) + { + context = createContext(); + Logger.Log($"Opened realm \"{context.Config.DatabasePath}\" at version {context.Config.SchemaVersion}"); + } - // creating a context will ensure our schema is up-to-date and migrated. - return context; + // creating a context will ensure our schema is up-to-date and migrated. + return context; + } } } @@ -87,8 +91,11 @@ namespace osu.Game.Database { base.Update(); - if (context?.Refresh() == true) - refreshes.Value++; + lock (contextLock) + { + if (context?.Refresh() == true) + refreshes.Value++; + } } private Realm createContext() @@ -137,8 +144,11 @@ namespace osu.Game.Database contextCreationLock.Wait(); - context?.Dispose(); - context = null; + lock (contextLock) + { + context?.Dispose(); + context = null; + } return new InvokeOnDisposal(this, endBlockingSection); From b51fd00ba34a8c201e79310834ca8e9ded9aeb4e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 1 Oct 2021 03:46:53 +0900 Subject: [PATCH 2/2] Guard against disposal in all context retrievals --- osu.Game/Database/RealmContextFactory.cs | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/osu.Game/Database/RealmContextFactory.cs b/osu.Game/Database/RealmContextFactory.cs index 0e18b68276..bf7feebdbf 100644 --- a/osu.Game/Database/RealmContextFactory.cs +++ b/osu.Game/Database/RealmContextFactory.cs @@ -51,7 +51,7 @@ namespace osu.Game.Database { if (context == null) { - context = createContext(); + context = CreateContext(); Logger.Log($"Opened realm \"{context.Config.DatabasePath}\" at version {context.Config.SchemaVersion}"); } @@ -73,14 +73,6 @@ namespace osu.Game.Database Filename += realm_extension; } - public Realm CreateContext() - { - if (IsDisposed) - throw new ObjectDisposedException(nameof(RealmContextFactory)); - - return createContext(); - } - /// /// Compact this realm. /// @@ -98,8 +90,11 @@ namespace osu.Game.Database } } - private Realm createContext() + public Realm CreateContext() { + if (IsDisposed) + throw new ObjectDisposedException(nameof(RealmContextFactory)); + try { contextCreationLock.Wait(); @@ -161,7 +156,10 @@ namespace osu.Game.Database protected override void Dispose(bool isDisposing) { - context?.Dispose(); + lock (contextLock) + { + context?.Dispose(); + } if (!IsDisposed) {