Merge pull request #16595 from peppy/realm-block-timeout-assert-failure

Fix a failed `BlockAllOperations` leaving update realm in unretrieved state
This commit is contained in:
Dan Balasescu 2022-01-25 16:03:13 +09:00 committed by GitHub
commit 1c6ad56821
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 6 deletions

View File

@ -87,6 +87,11 @@ namespace osu.Game.Tests.Database
hasThreadedUsage.Wait();
// Usually the host would run the synchronization context work per frame.
// For the sake of keeping this test simple (there's only one update invocation),
// let's replace it so we can ensure work is run immediately.
SynchronizationContext.SetSynchronizationContext(new ImmediateExecuteSynchronizationContext());
Assert.Throws<TimeoutException>(() =>
{
using (realm.BlockAllOperations())
@ -95,7 +100,17 @@ namespace osu.Game.Tests.Database
});
stopThreadedUsage.Set();
// Ensure we can block a second time after the usage has ended.
using (realm.BlockAllOperations())
{
}
});
}
private class ImmediateExecuteSynchronizationContext : SynchronizationContext
{
public override void Post(SendOrPostCallback d, object? state) => d(state);
}
}
}

View File

@ -639,18 +639,19 @@ namespace osu.Game.Database
}
catch
{
realmRetrievalLock.Release();
restoreOperation();
throw;
}
return new InvokeOnDisposal<RealmAccess>(this, factory =>
{
factory.realmRetrievalLock.Release();
Logger.Log(@"Restoring realm operations.", LoggingTarget.Database);
return new InvokeOnDisposal(restoreOperation);
void restoreOperation()
{
Logger.Log(@"Restoring realm operations.", LoggingTarget.Database);
realmRetrievalLock.Release();
// Post back to the update thread to revive any subscriptions.
syncContext?.Post(_ => ensureUpdateRealm(), null);
});
}
}
// https://github.com/realm/realm-dotnet/blob/32f4ebcc88b3e80a3b254412665340cd9f3bd6b5/Realm/Realm/Extensions/ReflectionExtensions.cs#L46