mirror of
https://github.com/ppy/osu.git
synced 2025-03-14 05:47:20 +08:00
Tidy up write usage class
This commit is contained in:
parent
5fa3a22f28
commit
8442b34e84
@ -22,6 +22,6 @@ namespace osu.Game.Database
|
||||
/// This method may block if a write is already active on a different thread.
|
||||
/// </summary>
|
||||
/// <returns>A usage containing a usable context.</returns>
|
||||
RealmWriteUsage GetForWrite();
|
||||
RealmContextFactory.RealmWriteUsage GetForWrite();
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
/// </summary>
|
||||
private readonly object writeLock = new object();
|
||||
|
||||
private ThreadLocal<bool> refreshCompleted = new ThreadLocal<bool>();
|
||||
|
||||
private bool rollbackRequired;
|
||||
|
||||
private int currentWriteUsages;
|
||||
|
||||
private Transaction currentWriteTransaction;
|
||||
|
||||
private static readonly GlobalStatistic<int> reads = GlobalStatistics.Get<int>("Realm", "Get (Read)");
|
||||
private static readonly GlobalStatistic<int> writes = GlobalStatistics.Get<int>("Realm", "Get (Write)");
|
||||
private static readonly GlobalStatistic<int> refreshes = GlobalStatistics.Get<int>("Realm", "Refreshes");
|
||||
private static readonly GlobalStatistic<int> commits = GlobalStatistics.Get<int>("Realm", "Commits");
|
||||
private static readonly GlobalStatistic<int> rollbacks = GlobalStatistics.Get<int>("Realm", "Rollbacks");
|
||||
private static readonly GlobalStatistic<int> contexts_open = GlobalStatistics.Get<int>("Realm", "Contexts (Open)");
|
||||
private static readonly GlobalStatistic<int> refreshes = GlobalStatistics.Get<int>("Realm", "Dirty Refreshes");
|
||||
private static readonly GlobalStatistic<int> contexts_created = GlobalStatistics.Get<int>("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<bool>();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Monitor.Exit(writeLock);
|
||||
}
|
||||
}
|
||||
|
||||
private void onMigration(Migration migration, ulong lastSchemaVersion)
|
||||
{
|
||||
}
|
||||
|
||||
public class RealmWriteUsage : InvokeOnDisposal<RealmContextFactory>
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,55 +0,0 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. 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<RealmWriteUsage> usageCompleted;
|
||||
|
||||
public bool RollbackRequired { get; private set; }
|
||||
|
||||
public RealmWriteUsage(Realm context, Action<RealmWriteUsage> onCompleted)
|
||||
{
|
||||
Context = context;
|
||||
usageCompleted = onCompleted;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether this write usage will commit a transaction on completion.
|
||||
/// If false, there is a parent usage responsible for transaction commit.
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user