mirror of
https://github.com/osukey/osukey.git
synced 2025-05-24 15:07:20 +09:00
Fix thread safety of realm Refresh
operation
Due to the lack of locking, there was a chance the the update thread `context` was retrieved just before the `flushContexts` call, followed by `.Refresh()` being run while the blocking behaviour was invoked. This can be seen in test failures such as https://ci.appveyor.com/project/peppy/osu/builds/39859786/tests. As an aside, I tried multiple different methods to avoid `lock()` on the update thread but they felt flaky. The overhead of lock when there's no contention is reportedly around 30-50ns, so likely not of concern. We can address it at a later point if it becomes one.
This commit is contained in:
parent
49090a0d1b
commit
567e9f33a9
@ -38,6 +38,8 @@ namespace osu.Game.Database
|
|||||||
private static readonly GlobalStatistic<int> pending_writes = GlobalStatistics.Get<int>("Realm", "Pending writes");
|
private static readonly GlobalStatistic<int> pending_writes = GlobalStatistics.Get<int>("Realm", "Pending writes");
|
||||||
private static readonly GlobalStatistic<int> active_usages = GlobalStatistics.Get<int>("Realm", "Active usages");
|
private static readonly GlobalStatistic<int> active_usages = GlobalStatistics.Get<int>("Realm", "Active usages");
|
||||||
|
|
||||||
|
private readonly object updateContextLock = new object();
|
||||||
|
|
||||||
private Realm context;
|
private Realm context;
|
||||||
|
|
||||||
public Realm Context
|
public Realm Context
|
||||||
@ -107,8 +109,11 @@ namespace osu.Game.Database
|
|||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
|
|
||||||
if (context?.Refresh() == true)
|
lock (updateContextLock)
|
||||||
refreshes.Value++;
|
{
|
||||||
|
if (context?.Refresh() == true)
|
||||||
|
refreshes.Value++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Realm createContext()
|
private Realm createContext()
|
||||||
@ -156,7 +161,9 @@ namespace osu.Game.Database
|
|||||||
Logger.Log(@"Flushing realm contexts...", LoggingTarget.Database);
|
Logger.Log(@"Flushing realm contexts...", LoggingTarget.Database);
|
||||||
|
|
||||||
var previousContext = context;
|
var previousContext = context;
|
||||||
context = null;
|
|
||||||
|
lock (updateContextLock)
|
||||||
|
context = null;
|
||||||
|
|
||||||
// wait for all threaded usages to finish
|
// wait for all threaded usages to finish
|
||||||
while (active_usages.Value > 0)
|
while (active_usages.Value > 0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user