WIP Make collections thread-safe and add safe iteration

Replaced static lists and dictionaries with thread-safe ConcurrentDictionary or ThreadLocal collections for various item components and systems. Updated all relevant code to use snapshots (ToArray, ToList) for safe iteration, and added helper methods for marking and clearing changed connections. These changes improve thread safety and prevent potential concurrency issues in multi-threaded scenarios.
This commit is contained in:
Eero
2025-12-28 04:59:56 +08:00
parent 90962b2328
commit 46595b1399
25 changed files with 519 additions and 245 deletions
@@ -2441,10 +2441,11 @@ namespace Barotrauma
{
if (c.IsPower)
{
Powered.ChangedConnections.Add(c);
foreach (Connection conn in c.Recipients)
Powered.MarkConnectionChanged(c);
// Use ToList() snapshot for thread-safe iteration
foreach (Connection conn in c.Recipients.ToList())
{
Powered.ChangedConnections.Add(conn);
Powered.MarkConnectionChanged(conn);
}
}
}
@@ -2980,7 +2981,8 @@ namespace Barotrauma
foreach (Connection c in connectionPanel.Connections)
{
if (connectionFilter != null && !connectionFilter(c)) { continue; }
foreach (Connection recipient in c.Recipients)
// Use ToList() snapshot for thread-safe iteration
foreach (Connection recipient in c.Recipients.ToList())
{
var component = recipient.Item.GetComponent<T>();
if (component != null)
@@ -3013,7 +3015,8 @@ namespace Barotrauma
foreach (Connection c in connectionPanel.Connections)
{
if (connectionFilter != null && !connectionFilter(c)) { continue; }
foreach (Connection recipient in c.Recipients)
// Use ToList() snapshot for thread-safe iteration
foreach (Connection recipient in c.Recipients.ToList())
{
var component = recipient.Item.GetComponent<T>();
if (component != null && !connectedComponents.Contains(component))
@@ -3067,12 +3070,13 @@ namespace Barotrauma
alreadySearched.Add(c);
static IEnumerable<Connection> GetRecipients(Connection c)
{
foreach (Connection recipient in c.Recipients)
// Use ToList() snapshot for thread-safe iteration
foreach (Connection recipient in c.Recipients.ToList())
{
yield return recipient;
}
//check circuit box inputs/outputs this connection is connected to
foreach (var circuitBoxConnection in c.CircuitBoxConnections)
foreach (var circuitBoxConnection in c.CircuitBoxConnections.ToArray())
{
yield return circuitBoxConnection.Connection;
}
@@ -3212,7 +3216,8 @@ namespace Barotrauma
if (signal.stepsTaken > 5 && signal.source != null)
{
int duplicateRecipients = 0;
foreach (var recipient in signal.source.LastSentSignalRecipients)
// Use ToList() snapshot for thread-safe iteration
foreach (var recipient in signal.source.LastSentSignalRecipients.ToList())
{
if (recipient == connection)
{