diff --git a/osu.Game/Database/IRealmFactory.cs b/osu.Game/Database/IRealmFactory.cs
index 0fffc3d7be..4a92a5683b 100644
--- a/osu.Game/Database/IRealmFactory.cs
+++ b/osu.Game/Database/IRealmFactory.cs
@@ -22,6 +22,6 @@ namespace osu.Game.Database
/// This method may block if a write is already active on a different thread.
///
/// A usage containing a usable context.
- RealmWriteUsage GetForWrite();
+ RealmContextFactory.RealmWriteUsage GetForWrite();
}
}
diff --git a/osu.Game/Database/RealmContextFactory.cs b/osu.Game/Database/RealmContextFactory.cs
index ea3549a9cd..dc8761fb3c 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.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Logging;
using osu.Framework.Platform;
@@ -13,6 +14,7 @@ namespace osu.Game.Database
public class RealmContextFactory : Component, IRealmFactory
{
private readonly Storage storage;
+
private const string database_name = @"client";
private const int schema_version = 5;
@@ -22,20 +24,11 @@ namespace osu.Game.Database
///
private readonly object writeLock = new object();
- private ThreadLocal refreshCompleted = new ThreadLocal();
-
- private bool rollbackRequired;
-
private int currentWriteUsages;
- private Transaction currentWriteTransaction;
-
private static readonly GlobalStatistic reads = GlobalStatistics.Get("Realm", "Get (Read)");
private static readonly GlobalStatistic writes = GlobalStatistics.Get("Realm", "Get (Write)");
- private static readonly GlobalStatistic refreshes = GlobalStatistics.Get("Realm", "Refreshes");
- private static readonly GlobalStatistic commits = GlobalStatistics.Get("Realm", "Commits");
- private static readonly GlobalStatistic rollbacks = GlobalStatistics.Get("Realm", "Rollbacks");
- private static readonly GlobalStatistic contexts_open = GlobalStatistics.Get("Realm", "Contexts (Open)");
+ private static readonly GlobalStatistic refreshes = GlobalStatistics.Get("Realm", "Dirty Refreshes");
private static readonly GlobalStatistic contexts_created = GlobalStatistics.Get("Realm", "Contexts (Created)");
private Realm context;
@@ -72,24 +65,8 @@ namespace osu.Game.Database
writes.Value++;
Monitor.Enter(writeLock);
- Realm realm;
-
- try
- {
- realm = createContext();
-
- currentWriteTransaction ??= realm.BeginWrite();
- }
- catch
- {
- // retrieval of a context could trigger a fatal error.
- Monitor.Exit(writeLock);
- throw;
- }
-
Interlocked.Increment(ref currentWriteUsages);
-
- return new RealmWriteUsage(realm, usageCompleted) { IsTransactionLeader = currentWriteTransaction != null && currentWriteUsages == 1 };
+ return new RealmWriteUsage(this);
}
protected override void Update()
@@ -111,41 +88,25 @@ namespace osu.Game.Database
});
}
- private void usageCompleted(RealmWriteUsage usage)
- {
- int usages = Interlocked.Decrement(ref currentWriteUsages);
-
- try
- {
- rollbackRequired |= usage.RollbackRequired;
-
- if (usages == 0)
- {
- if (rollbackRequired)
- {
- rollbacks.Value++;
- currentWriteTransaction?.Rollback();
- }
- else
- {
- commits.Value++;
- currentWriteTransaction?.Commit();
- }
-
- currentWriteTransaction = null;
- rollbackRequired = false;
-
- refreshCompleted = new ThreadLocal();
- }
- }
- finally
- {
- Monitor.Exit(writeLock);
- }
- }
-
private void onMigration(Migration migration, ulong lastSchemaVersion)
{
}
+
+ public class RealmWriteUsage : InvokeOnDisposal
+ {
+ public readonly Realm Context;
+
+ public RealmWriteUsage(RealmContextFactory factory)
+ : base(factory, usageCompleted)
+ {
+ Context = factory.createContext();
+ Context.BeginWrite();
+ }
+
+ private static void usageCompleted(RealmContextFactory factory)
+ {
+ Monitor.Exit(factory.writeLock);
+ }
+ }
}
}
diff --git a/osu.Game/Database/RealmWriteUsage.cs b/osu.Game/Database/RealmWriteUsage.cs
deleted file mode 100644
index 35e30e8123..0000000000
--- a/osu.Game/Database/RealmWriteUsage.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
-// See the LICENCE file in the repository root for full licence text.
-
-using System;
-using Realms;
-
-namespace osu.Game.Database
-{
- public class RealmWriteUsage : IDisposable
- {
- public readonly Realm Context;
- private readonly Action usageCompleted;
-
- public bool RollbackRequired { get; private set; }
-
- public RealmWriteUsage(Realm context, Action onCompleted)
- {
- Context = context;
- usageCompleted = onCompleted;
- }
-
- ///
- /// Whether this write usage will commit a transaction on completion.
- /// If false, there is a parent usage responsible for transaction commit.
- ///
- public bool IsTransactionLeader;
-
- private bool isDisposed;
-
- protected void Dispose(bool disposing)
- {
- if (isDisposed) return;
-
- isDisposed = true;
-
- usageCompleted?.Invoke(this);
- }
-
- public void Rollback(Exception error = null)
- {
- RollbackRequired = true;
- }
-
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- ~RealmWriteUsage()
- {
- Dispose(false);
- }
- }
-}