Some collection modified safety in Dispatch (seeing a few exceptions on Rust staging)

This commit is contained in:
Garry Newman 2020-02-28 11:05:27 +00:00
parent 5aeeaa0cd7
commit e6c0167c48

View File

@ -65,12 +65,23 @@ internal static void Init()
SteamAPI_ManualDispatch_Init();
}
/// <summary>
/// Make sure we don't call Frame in a callback - because that'll cause some issues for everyone.
/// </summary>
static bool runningFrame = false;
/// <summary>
/// Calls RunFrame and processes events from this Steam Pipe
/// </summary>
internal static void Frame( HSteamPipe pipe )
{
if ( runningFrame )
return;
try
{
runningFrame = true;
SteamAPI_ManualDispatch_RunFrame( pipe );
SteamNetworkingUtils.OutputDebugMessages();
@ -88,6 +99,19 @@ internal static void Frame( HSteamPipe pipe )
}
}
}
finally
{
runningFrame = false;
}
}
/// <summary>
/// To be safe we don't call the continuation functions while iterating
/// the Callback list. This is maybe overly safe because the only way this
/// could be an issue is if the callback list is modified in the continuation
/// which would only happen if starting or shutting down in the callback.
/// </summary>
static List<Action<IntPtr>> actionsToCall = new List<Action<IntPtr>>();
/// <summary>
/// A callback is a general global message
@ -108,13 +132,22 @@ private static void ProcessCallback( CallbackMsg_t msg, bool isServer )
if ( Callbacks.TryGetValue( msg.Type, out var list ) )
{
actionsToCall.Clear();
foreach ( var item in list )
{
if ( item.server != isServer )
continue;
item.action( msg.Data );
actionsToCall.Add( item.action );
}
foreach ( var action in actionsToCall )
{
action( msg.Data );
}
actionsToCall.Clear();
}
}