Avoid attempting to fetch a non-managed RealmLive instance from the realm backing

For compatibility reasons, we quite often convert completely unmanaged
instances to `ILive`s so they fit the required parameters of a property
or method call. This ensures such cases will not cause any issues when
trying to interact with the underlying data.

Originally I had this allowing write operations, but that seems a bit
unsafe (when performing a write one would assume that the underlying
data is being persisted, whereas in this case it is not). We can change
this if the requirements change in the future, but I think throwing is
the safest bet for now.
This commit is contained in:
Dean Herbert
2021-11-26 14:39:35 +09:00
parent 3bc8f21935
commit 40d1b97af1
4 changed files with 41 additions and 4 deletions

View File

@ -17,6 +17,8 @@ namespace osu.Game.Database
{
public Guid ID { get; }
public bool IsManaged { get; }
private readonly SynchronizationContext? fetchedContext;
private readonly int fetchedThreadId;
@ -33,8 +35,13 @@ namespace osu.Game.Database
{
this.data = data;
fetchedContext = SynchronizationContext.Current;
fetchedThreadId = Thread.CurrentThread.ManagedThreadId;
if (data.IsManaged)
{
IsManaged = true;
fetchedContext = SynchronizationContext.Current;
fetchedThreadId = Thread.CurrentThread.ManagedThreadId;
}
ID = data.ID;
}
@ -75,13 +82,18 @@ namespace osu.Game.Database
/// Perform a write operation on this live object.
/// </summary>
/// <param name="perform">The action to perform.</param>
public void PerformWrite(Action<T> perform) =>
public void PerformWrite(Action<T> perform)
{
if (!IsManaged)
throw new InvalidOperationException("Can't perform writes on a non-managed underlying value");
PerformRead(t =>
{
var transaction = t.Realm.BeginWrite();
perform(t);
transaction.Commit();
});
}
public T Value
{
@ -102,7 +114,7 @@ namespace osu.Game.Database
}
}
private bool originalDataValid => isCorrectThread && data.IsValid;
private bool originalDataValid => !IsManaged || (isCorrectThread && data.IsValid);
// this matches realm's internal thread validation (see https://github.com/realm/realm-dotnet/blob/903b4d0b304f887e37e2d905384fb572a6496e70/Realm/Realm/Native/SynchronizationContextScheduler.cs#L72)
private bool isCorrectThread