mirror of
https://github.com/ppy/osu.git
synced 2024-11-14 17:17:24 +08:00
Ensure realm blocks until all threaded usages are completed
This commit is contained in:
parent
9c0abae2b0
commit
cfd3bdf888
@ -133,20 +133,43 @@ namespace osu.Game.Database
|
|||||||
if (IsDisposed)
|
if (IsDisposed)
|
||||||
throw new ObjectDisposedException(nameof(RealmContextFactory));
|
throw new ObjectDisposedException(nameof(RealmContextFactory));
|
||||||
|
|
||||||
|
// TODO: this can be added for safety once we figure how to bypass in test
|
||||||
|
// if (!ThreadSafety.IsUpdateThread)
|
||||||
|
// throw new InvalidOperationException($"{nameof(BlockAllOperations)} must be called from the update thread.");
|
||||||
|
|
||||||
Logger.Log(@"Blocking realm operations.", LoggingTarget.Database);
|
Logger.Log(@"Blocking realm operations.", LoggingTarget.Database);
|
||||||
|
|
||||||
contextCreationLock.Wait();
|
try
|
||||||
|
{
|
||||||
|
contextCreationLock.Wait();
|
||||||
|
|
||||||
context?.Dispose();
|
const int sleep_length = 200;
|
||||||
context = null;
|
int timeout = 5000;
|
||||||
|
|
||||||
return new InvokeOnDisposal<RealmContextFactory>(this, endBlockingSection);
|
context?.Dispose();
|
||||||
|
context = null;
|
||||||
|
|
||||||
static void endBlockingSection(RealmContextFactory factory)
|
// see https://github.com/realm/realm-dotnet/discussions/2657
|
||||||
|
while (!Compact())
|
||||||
|
{
|
||||||
|
Thread.Sleep(sleep_length);
|
||||||
|
timeout -= sleep_length;
|
||||||
|
|
||||||
|
if (timeout < 0)
|
||||||
|
throw new TimeoutException("Took too long to acquire lock");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
contextCreationLock.Release();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new InvokeOnDisposal<RealmContextFactory>(this, factory =>
|
||||||
{
|
{
|
||||||
factory.contextCreationLock.Release();
|
factory.contextCreationLock.Release();
|
||||||
Logger.Log(@"Restoring realm operations.", LoggingTarget.Database);
|
Logger.Log(@"Restoring realm operations.", LoggingTarget.Database);
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool isDisposing)
|
protected override void Dispose(bool isDisposing)
|
||||||
@ -155,8 +178,8 @@ namespace osu.Game.Database
|
|||||||
|
|
||||||
if (!IsDisposed)
|
if (!IsDisposed)
|
||||||
{
|
{
|
||||||
// intentionally block all operations indefinitely. this ensures that nothing can start consuming a new context after disposal.
|
// intentionally block context creation indefinitely. this ensures that nothing can start consuming a new context after disposal.
|
||||||
BlockAllOperations();
|
contextCreationLock.Wait();
|
||||||
contextCreationLock.Dispose();
|
contextCreationLock.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user