fix(O-T4): thread-safety lock in DatDatabaseWrapper + drop unused using
Code-review findings on T4: 1. Added lock(_lock) around _db.TryGet and TryGetFileBytes in DatDatabaseWrapper, matching WB's DefaultDatDatabase pattern. ObjectMeshManager.PrepareMeshDataAsync runs on the thread pool, so concurrent dat access through the adapter must be serialized — our underlying DatCollection is not documented as thread-safe. 2. Removed unused `using WorldBuilder.Shared.Models;` from WbMeshAdapter.cs (its only purpose was TerrainEntry, which moved to AcDream.Core in T2). Build green; tests green (1147 passing, 8 pre-existing failures baseline). Spec: docs/superpowers/specs/2026-05-21-phase-o-dat-path-unification-design.md Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c0326523ac
commit
a9ccc5acf5
2 changed files with 21 additions and 8 deletions
|
|
@ -118,6 +118,7 @@ internal sealed class DatDatabaseWrapper : IDatDatabase
|
|||
{
|
||||
private readonly DatDatabase _db;
|
||||
private readonly ConcurrentDictionary<(Type, uint), IDBObj> _cache = new();
|
||||
private readonly object _lock = new();
|
||||
|
||||
public DatDatabaseWrapper(DatDatabase db)
|
||||
{
|
||||
|
|
@ -142,20 +143,33 @@ internal sealed class DatDatabaseWrapper : IDatDatabase
|
|||
return true;
|
||||
}
|
||||
|
||||
if (_db.TryGet<T>(fileId, out value))
|
||||
lock (_lock)
|
||||
{
|
||||
_cache.TryAdd((typeof(T), fileId), value);
|
||||
return true;
|
||||
if (_db.TryGet<T>(fileId, out value))
|
||||
{
|
||||
_cache.TryAdd((typeof(T), fileId), value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryGetFileBytes(uint fileId, [MaybeNullWhen(false)] out byte[] value) =>
|
||||
_db.TryGetFileBytes(fileId, out value);
|
||||
public bool TryGetFileBytes(uint fileId, [MaybeNullWhen(false)] out byte[] value)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
return _db.TryGetFileBytes(fileId, out value);
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryGetFileBytes(uint fileId, ref byte[] bytes, out int bytesRead) =>
|
||||
_db.TryGetFileBytes(fileId, ref bytes, out bytesRead);
|
||||
public bool TryGetFileBytes(uint fileId, ref byte[] bytes, out int bytesRead)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
return _db.TryGetFileBytes(fileId, ref bytes, out bytesRead);
|
||||
}
|
||||
}
|
||||
|
||||
public bool TrySave<T>(T obj, int iteration = 0) where T : IDBObj =>
|
||||
throw new NotSupportedException("DatDatabaseWrapper is read-only.");
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ using DatReaderWriter.DBObjs;
|
|||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Silk.NET.OpenGL;
|
||||
using WorldBuilder.Shared.Models;
|
||||
using WorldBuilder.Shared.Services;
|
||||
|
||||
namespace AcDream.App.Rendering.Wb;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue