From 0dca9c8c464eae0440c4426401d76e52897e8afa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 12 Jan 2021 14:36:35 +0900 Subject: [PATCH] Tidy up RealmContextFactory; remove delete/dispose method which wouldn't work due to threading --- osu.Game/Database/RealmContextFactory.cs | 52 +++++++++--------------- 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/osu.Game/Database/RealmContextFactory.cs b/osu.Game/Database/RealmContextFactory.cs index e0fd44ed4a..e11379869a 100644 --- a/osu.Game/Database/RealmContextFactory.cs +++ b/osu.Game/Database/RealmContextFactory.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.Threading; +using osu.Framework.Logging; using osu.Framework.Platform; using osu.Framework.Statistics; using Realms; @@ -16,8 +17,11 @@ public class RealmContextFactory : IRealmFactory private const int schema_version = 5; - private ThreadLocal threadContexts; + private readonly ThreadLocal threadContexts; + /// + /// Lock object which is held for the duration of a write operation (via ). + /// private readonly object writeLock = new object(); private ThreadLocal refreshCompleted = new ThreadLocal(); @@ -32,10 +36,11 @@ public RealmContextFactory(Storage storage) { this.storage = storage; - recreateThreadContexts(); + threadContexts = new ThreadLocal(createContext, true); - using (CreateContext()) + using (var realm = Get()) { + Logger.Log($"Opened realm {database_name} at version {realm.Config.SchemaVersion}"); // creating a context will ensure our schema is up-to-date and migrated. } } @@ -95,7 +100,7 @@ private Realm getContextForCurrentThread() var context = threadContexts.Value; if (context?.IsClosed != false) - threadContexts.Value = context = CreateContext(); + threadContexts.Value = context = createContext(); contexts_open.Value = threadContexts.Values.Count; @@ -110,6 +115,17 @@ private Realm getContextForCurrentThread() return context; } + private Realm createContext() + { + contexts_created.Value++; + + return Realm.GetInstance(new RealmConfiguration(storage.GetFullPath($"{database_name}.realm", true)) + { + SchemaVersion = schema_version, + MigrationCallback = onMigration, + }); + } + private void usageCompleted(RealmWriteUsage usage) { int usages = Interlocked.Decrement(ref currentWriteUsages); @@ -142,33 +158,5 @@ private void usageCompleted(RealmWriteUsage usage) Monitor.Exit(writeLock); } } - - private void recreateThreadContexts() - { - // Contexts for other threads are not disposed as they may be in use elsewhere. Instead, fresh contexts are exposed - // for other threads to use, and we rely on the finalizer inside OsuDbContext to handle their previous contexts - threadContexts?.Value.Dispose(); - threadContexts = new ThreadLocal(CreateContext, true); - } - - protected virtual Realm CreateContext() - { - contexts_created.Value++; - - return Realm.GetInstance(new RealmConfiguration(storage.GetFullPath($"{database_name}.realm", true)) - { - SchemaVersion = schema_version, - MigrationCallback = onMigration, - }); - } - - public void ResetDatabase() - { - lock (writeLock) - { - recreateThreadContexts(); - storage.DeleteDatabase(database_name); - } - } } }