Skip to content

Commit

Permalink
move PacketData and list management to shared and reimplement as doub…
Browse files Browse the repository at this point in the history
…ly linked list. (#2164)
  • Loading branch information
Wraith2 authored Oct 25, 2023
1 parent 57d287c commit b86ddf1
Show file tree
Hide file tree
Showing 3 changed files with 241 additions and 248 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ internal abstract partial class TdsParserStateObject
// Timeout variables
private readonly WeakReference _cancellationOwner = new WeakReference(null);

// Async
// Async

//////////////////
// Constructors //
Expand Down Expand Up @@ -1072,12 +1072,18 @@ internal bool TryReadNetworkPacket()
{
if (_snapshotReplay)
{
if (_snapshot.Replay())
#if DEBUG
// in debug builds stack traces contain line numbers so if we want to be
// able to compare the stack traces they must all be created in the same
// location in the code
string stackTrace = Environment.StackTrace;
#endif
if (_snapshot.MoveNext())
{
#if DEBUG
if (s_checkNetworkPacketRetryStacks)
{
_snapshot.CheckStack(Environment.StackTrace);
_snapshot.CheckStack(stackTrace);
}
#endif
return true;
Expand All @@ -1087,7 +1093,7 @@ internal bool TryReadNetworkPacket()
{
if (s_checkNetworkPacketRetryStacks)
{
_lastStack = Environment.StackTrace;
_lastStack = stackTrace;
}
}
#endif
Expand Down Expand Up @@ -1123,7 +1129,7 @@ internal bool TryReadNetworkPacket()
internal void PrepareReplaySnapshot()
{
_networkPacketTaskSource = null;
_snapshot.PrepareReplay();
_snapshot.MoveToStart();
}

internal void ReadSniSyncOverAsync()
Expand Down Expand Up @@ -1434,7 +1440,7 @@ internal void ReadSni(TaskCompletionSource<object> completion)
Timeout.Infinite,
Timeout.Infinite
);


// -1 == Infinite
// 0 == Already timed out (NOTE: To simulate the same behavior as sync we will only timeout on 0 if we receive an IO Pending from SNI)
Expand Down Expand Up @@ -1740,10 +1746,10 @@ public void ProcessSniPacket(PacketHandle packet, uint error)

if (_snapshot != null)
{
_snapshot.PushBuffer(_inBuff, _inBytesRead);
_snapshot.AppendPacketData(_inBuff, _inBytesRead);
if (_snapshotReplay)
{
_snapshot.Replay();
_snapshot.MoveNext();
#if DEBUG
_snapshot.AssertCurrent();
#endif
Expand Down Expand Up @@ -3024,137 +3030,7 @@ internal void CloneCleanupAltMetaDataSetArray()

sealed partial class StateSnapshot
{
private sealed partial class PacketData
{
public byte[] Buffer;
public int Read;
public PacketData Prev;

public void SetStack(string value)
{
SetStackInternal(value);
}
partial void SetStackInternal(string value);

public void Clear()
{
Buffer = null;
Read = 0;
Prev = null;
SetStackInternal(null);
}
}

#if DEBUG
private sealed partial class PacketData
{
public string Stack;

partial void SetStackInternal(string value)
{
Stack = value;
}
}


#endif
private PacketData _snapshotInBuffList;
private PacketData _sparePacket;

internal byte[] _plpBuffer;

private int _snapshotInBuffCount;

#if DEBUG
internal void AssertCurrent()
{
Debug.Assert(_snapshotInBuffCurrent == _snapshotInBuffCount, "Should not be reading new packets when not replaying last packet");
}

internal void CheckStack(string trace)
{
PacketData prev = _snapshotInBuffList?.Prev;
if (prev.Stack == null)
{
prev.Stack = trace;
}
else
{
Debug.Assert(_stateObj._permitReplayStackTraceToDiffer || prev.Stack.ToString() == trace.ToString(), "The stack trace on subsequent replays should be the same");
}
}
#endif
internal void PushBuffer(byte[] buffer, int read)
{
#if DEBUG
for (PacketData current = _snapshotInBuffList; current != null; current = current.Prev)
{
Debug.Assert(!object.ReferenceEquals(current.Buffer, buffer));
}
#endif

PacketData packetData = _sparePacket;
if (packetData is null)
{
packetData = new PacketData();
}
else
{
_sparePacket = null;
}
packetData.Buffer = buffer;
packetData.Read = read;
packetData.Prev = _snapshotInBuffList;
#if DEBUG
packetData.SetStack(_stateObj._lastStack);
#endif
_snapshotInBuffList = packetData;
_snapshotInBuffCount++;
}

internal bool Replay()
{
if (_snapshotInBuffCurrent < _snapshotInBuffCount)
{
PacketData next = _snapshotInBuffList;
for (
int position = (_snapshotInBuffCount - 1);
position != _snapshotInBuffCurrent;
position -= 1
)
{
next = next.Prev;
}
_stateObj._inBuff = next.Buffer;
_stateObj._inBytesUsed = 0;
_stateObj._inBytesRead = next.Read;
_snapshotInBuffCurrent++;
return true;
}

return false;
}

internal void Snap(TdsParserStateObject state)
{
_snapshotInBuffList = null;
_snapshotInBuffCount = 0;
_snapshotInBuffCurrent = 0;

CaptureAsStart(state);
}

internal void Clear()
{
PacketData packet = _snapshotInBuffList;
_snapshotInBuffList = null;
_snapshotInBuffCount = 0;

packet.Clear();
_sparePacket = packet;

ClearCore();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1164,7 +1164,7 @@ internal bool TrySkipBytes(int num)
/////////////////////////////////////////

#if DEBUG
StackTrace _lastStack;
string _lastStack;
#endif

internal bool TryReadNetworkPacket()
Expand All @@ -1179,12 +1179,18 @@ internal bool TryReadNetworkPacket()
{
if (_snapshotReplay)
{
if (_snapshot.Replay())
#if DEBUG
// in debug builds stack traces contain line numbers so if we want to be
// able to compare the stack traces they must all be created in the same
// location in the code
string stackTrace = Environment.StackTrace;
#endif
if (_snapshot.MoveNext())
{
#if DEBUG
if (s_checkNetworkPacketRetryStacks)
{
_snapshot.CheckStack(new StackTrace());
_snapshot.CheckStack(stackTrace);
}
#endif
return true;
Expand All @@ -1194,7 +1200,7 @@ internal bool TryReadNetworkPacket()
{
if (s_checkNetworkPacketRetryStacks)
{
_lastStack = new StackTrace();
_lastStack = stackTrace;
}
}
#endif
Expand Down Expand Up @@ -1230,7 +1236,7 @@ internal bool TryReadNetworkPacket()
internal void PrepareReplaySnapshot()
{
_networkPacketTaskSource = null;
_snapshot.PrepareReplay();
_snapshot.MoveToStart();
}

internal void ReadSniSyncOverAsync()
Expand Down Expand Up @@ -1884,10 +1890,10 @@ public void ProcessSniPacket(IntPtr packet, uint error)

if (_snapshot != null)
{
_snapshot.PushBuffer(_inBuff, _inBytesRead);
_snapshot.AppendPacketData(_inBuff, _inBytesRead);
if (_snapshotReplay)
{
_snapshot.Replay();
_snapshot.MoveNext();
#if DEBUG
_snapshot.AssertCurrent();
#endif
Expand Down Expand Up @@ -3189,98 +3195,10 @@ internal void CloneCleanupAltMetaDataSetArray()
}
}

class PacketData
{
public byte[] Buffer;
public int Read;
#if DEBUG
public StackTrace Stack;
#endif
}

sealed partial class StateSnapshot
{
private List<PacketData> _snapshotInBuffs;

public StateSnapshot()
{
_snapshotInBuffs = new List<PacketData>();
}

#if DEBUG
internal void AssertCurrent()
{
Debug.Assert(_snapshotInBuffCurrent == _snapshotInBuffs.Count, "Should not be reading new packets when not replaying last packet");
}

internal void CheckStack(StackTrace trace)
{
PacketData prev = _snapshotInBuffs[_snapshotInBuffCurrent - 1];
if (prev.Stack == null)
{
prev.Stack = trace;
}
else
{
Debug.Assert(_stateObj._permitReplayStackTraceToDiffer || prev.Stack.ToString() == trace.ToString(), "The stack trace on subsequent replays should be the same");
}
}
#endif

internal void PushBuffer(byte[] buffer, int read)
{
#if DEBUG
if (_snapshotInBuffs != null && _snapshotInBuffs.Count > 0)
{
foreach (PacketData packet in _snapshotInBuffs)
{
if (object.ReferenceEquals(packet.Buffer, buffer))
{
Debug.Assert(false,"buffer is already present in packet list");
}
}
}
#endif

PacketData packetData = new PacketData();
packetData.Buffer = buffer;
packetData.Read = read;
#if DEBUG
packetData.Stack = _stateObj._lastStack;
#endif

_snapshotInBuffs.Add(packetData);
}

internal bool Replay()
{
if (_snapshotInBuffCurrent < _snapshotInBuffs.Count)
{
PacketData next = _snapshotInBuffs[_snapshotInBuffCurrent];
_stateObj._inBuff = next.Buffer;
_stateObj._inBytesUsed = 0;
_stateObj._inBytesRead = next.Read;
_snapshotInBuffCurrent++;
return true;
}

return false;
}

internal void Snap(TdsParserStateObject state)
{
_snapshotInBuffs.Clear();
_snapshotInBuffCurrent = 0;

CaptureAsStart(state);
}

internal void Clear()
{
_snapshotInBuffs.Clear();

ClearCore();
}
}
}
}
Loading

0 comments on commit b86ddf1

Please sign in to comment.