Fix concurrent access issues with ConnectedClients
Replaced direct access to GameMain.Server.ConnectedClients with array snapshots in multiple server-side classes to prevent concurrent modification issues during parallel updates. Also updated PhysicsBody and LevelTrigger to avoid static/shared state in parallel contexts, improving thread safety and reliability.
This commit is contained in:
@@ -673,13 +673,17 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly List<Entity> triggerersToRemove = new List<Entity>();
|
||||
public static void RemoveInActiveTriggerers(PhysicsBody physicsBody, HashSet<Entity> triggerers)
|
||||
{
|
||||
if (physicsBody == null) { return; }
|
||||
|
||||
triggerersToRemove.Clear();
|
||||
foreach (var triggerer in triggerers)
|
||||
// Use local list instead of static field to avoid concurrent access issues during parallel updates
|
||||
var triggerersToRemove = new List<Entity>();
|
||||
|
||||
// Create snapshot to avoid concurrent modification during enumeration
|
||||
var triggererSnapshot = triggerers.ToArray();
|
||||
|
||||
foreach (var triggerer in triggererSnapshot)
|
||||
{
|
||||
if (triggerer.Removed)
|
||||
{
|
||||
|
||||
@@ -834,6 +834,12 @@ namespace Barotrauma
|
||||
if (!IsValidValue(simPosition, "position", -1e10f, 1e10f)) { return false; }
|
||||
if (!IsValidValue(rotation, "rotation")) { return false; }
|
||||
|
||||
if (PhysicsBodyQueue.IsInParallelContext)
|
||||
{
|
||||
PhysicsBodyQueue.Enqueue(() => SetTransform(simPosition, rotation, setPrevTransform));
|
||||
return true;
|
||||
}
|
||||
|
||||
FarseerBody.SetTransform(simPosition, rotation);
|
||||
if (setPrevTransform) { SetPrevTransform(simPosition, rotation); }
|
||||
return true;
|
||||
@@ -848,6 +854,12 @@ namespace Barotrauma
|
||||
if (!IsValidValue(simPosition, "position", -1e10f, 1e10f)) { return false; }
|
||||
if (!IsValidValue(rotation, "rotation")) { return false; }
|
||||
|
||||
if (PhysicsBodyQueue.IsInParallelContext)
|
||||
{
|
||||
PhysicsBodyQueue.Enqueue(() => SetTransformIgnoreContacts(simPosition, rotation, setPrevTransform));
|
||||
return true;
|
||||
}
|
||||
|
||||
FarseerBody.SetTransformIgnoreContacts(ref simPosition, rotation);
|
||||
if (setPrevTransform) { SetPrevTransform(simPosition, rotation); }
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user