fix(core): Fixes threading issue and adds threadguard (#565)

Setting `m.NetState = null` from a different thread caused `Mobile.Delta` and `NetState.Send` to run from a separate thread which cannot happen.
- [X] Fixes this issue
- [X] Adds THREADGUARD compiler constant as an option to trace this in the future.
This commit is contained in:
Kamron Batman 2021-04-08 21:56:31 -07:00 committed by GitHub
parent 47bbd72e55
commit 529abb4283
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 118 additions and 81 deletions

View file

@ -17,6 +17,7 @@ using System;
using System.Buffers;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Sockets;
@ -453,6 +454,16 @@ namespace Server.Network
public bool GetSendBuffer(out CircularBuffer<byte> cBuffer)
{
#if THREADGUARD
if (Thread.CurrentThread != Core.Thread)
{
Utility.PushColor(ConsoleColor.Red);
Console.WriteLine("Attempting to get pipe buffer from wrong thread!");
Console.WriteLine(new StackTrace());
Utility.PopColor();
return;
}
#endif
var result = SendPipe.Writer.TryGetMemory();
cBuffer = new CircularBuffer<byte>(result.Buffer);
@ -1056,13 +1067,6 @@ namespace Server.Network
return;
}
var m = Mobile;
if (m != null)
{
m.NetState = null;
Mobile = null;
}
try
{
if (_disconnectReason != string.Empty)
@ -1108,9 +1112,28 @@ namespace Server.Network
{
TraceDisconnect(_disconnectReason, _toString);
#if THREADGUARD
if (Thread.CurrentThread != Core.Thread)
{
Utility.PushColor(ConsoleColor.Red);
Console.WriteLine("Attempting to dispose a netstate from an invalid thread!");
Console.WriteLine(new StackTrace());
Utility.PopColor();
return;
}
#endif
RecvPipe.Writer.Close();
SendPipe.Writer.Close();
var m = Mobile;
Mobile = null;
if (m?.NetState == this)
{
m.NetState = null;
}
var a = Account;
Gumps.Clear();