1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-13 16:32:54 +08:00

Use a more reliable method of reviving the update thread realm after blocking

This commit is contained in:
Dean Herbert 2022-01-21 22:40:18 +09:00
parent 3b11235d3c
commit ad3a01dc06
2 changed files with 25 additions and 23 deletions

View File

@ -69,30 +69,29 @@ namespace osu.Game.Database
private Realm? context;
public Realm Context
public Realm Context => ensureUpdateContext();
private Realm ensureUpdateContext()
{
get
if (!ThreadSafety.IsUpdateThread)
throw new InvalidOperationException(@$"Use {nameof(createContext)} when performing realm operations from a non-update thread");
lock (contextLock)
{
if (!ThreadSafety.IsUpdateThread)
throw new InvalidOperationException(@$"Use {nameof(createContext)} when performing realm operations from a non-update thread");
lock (contextLock)
if (context == null)
{
if (context == null)
{
context = createContext();
Logger.Log(@$"Opened realm ""{context.Config.DatabasePath}"" at version {context.Config.SchemaVersion}");
context = createContext();
Logger.Log(@$"Opened realm ""{context.Config.DatabasePath}"" at version {context.Config.SchemaVersion}");
// Resubscribe any subscriptions
foreach (var action in subscriptionActions.Keys)
registerSubscription(action);
}
Debug.Assert(context != null);
// creating a context will ensure our schema is up-to-date and migrated.
return context;
// Resubscribe any subscriptions
foreach (var action in subscriptionActions.Keys)
registerSubscription(action);
}
Debug.Assert(context != null);
// creating a context will ensure our schema is up-to-date and migrated.
return context;
}
}
@ -506,6 +505,8 @@ namespace osu.Game.Database
if (isDisposed)
throw new ObjectDisposedException(nameof(RealmContextFactory));
SynchronizationContext syncContext;
try
{
contextCreationLock.Wait();
@ -515,6 +516,8 @@ namespace osu.Game.Database
if (!ThreadSafety.IsUpdateThread && context != null)
throw new InvalidOperationException(@$"{nameof(BlockAllOperations)} must be called from the update thread.");
syncContext = SynchronizationContext.Current;
Logger.Log(@"Blocking realm operations.", LoggingTarget.Database);
context?.Dispose();
@ -553,6 +556,9 @@ namespace osu.Game.Database
{
factory.contextCreationLock.Release();
Logger.Log(@"Restoring realm operations.", LoggingTarget.Database);
// Post back to the update thread to revive any subscriptions.
syncContext?.Post(_ => ensureUpdateContext(), null);
});
}

View File

@ -33,10 +33,6 @@ namespace osu.Game.Overlays.Settings.Sections.DebugSettings
using (realmFactory.BlockAllOperations())
{
}
// retrieve context to revive realm subscriptions.
// TODO: should we do this from OsuGame or RealmContextFactory or something? Answer: yes.
var _ = realmFactory.Context;
}
},
};