Skip to content

Commit

Permalink
Merge TDSParserStateObject.StateSnapshot state flags (#2132)
Browse files Browse the repository at this point in the history
  • Loading branch information
Wraith2 committed Sep 15, 2023
1 parent 816a7d3 commit cc5f05a
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 183 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ internal abstract partial class TdsParserStateObject
private readonly WeakReference _cancellationOwner = new WeakReference(null);

// Async
private SnapshottedStateFlags _snapshottedState;

//////////////////
// Constructors //
Expand Down Expand Up @@ -279,53 +278,6 @@ internal void StartSession(object cancellationOwner)
_cancellationOwner.Target = cancellationOwner;
}

private void SetSnapshottedState(SnapshottedStateFlags flag, bool value)
{
if (value)
{
_snapshottedState |= flag;
}
else
{
_snapshottedState &= ~flag;
}
}

private bool GetSnapshottedState(SnapshottedStateFlags flag)
{
return (_snapshottedState & flag) == flag;
}

internal bool HasOpenResult
{
get => GetSnapshottedState(SnapshottedStateFlags.OpenResult);
set => SetSnapshottedState(SnapshottedStateFlags.OpenResult, value);
}

internal bool HasPendingData
{
get => GetSnapshottedState(SnapshottedStateFlags.PendingData);
set => SetSnapshottedState(SnapshottedStateFlags.PendingData, value);
}

internal bool HasReceivedError
{
get => GetSnapshottedState(SnapshottedStateFlags.ErrorTokenReceived);
set => SetSnapshottedState(SnapshottedStateFlags.ErrorTokenReceived, value);
}

internal bool HasReceivedAttention
{
get => GetSnapshottedState(SnapshottedStateFlags.AttentionReceived);
set => SetSnapshottedState(SnapshottedStateFlags.AttentionReceived, value);
}

internal bool HasReceivedColumnMetadata
{
get => GetSnapshottedState(SnapshottedStateFlags.ColMetaDataReceived);
set => SetSnapshottedState(SnapshottedStateFlags.ColMetaDataReceived, value);
}

///////////////////////////////////////
// Buffer read methods - data values //
///////////////////////////////////////
Expand Down Expand Up @@ -3114,8 +3066,6 @@ private sealed partial class PacketData

private int _snapshotInBuffCount;

private SnapshottedStateFlags _state;

#if DEBUG
internal void AssertCurrent()
{
Expand Down Expand Up @@ -3218,45 +3168,6 @@ internal void Snap(TdsParserStateObject state)
PushBuffer(_stateObj._inBuff, _stateObj._inBytesRead);
}

internal void ResetSnapshotState()
{
// go back to the beginning
_snapshotInBuffCurrent = 0;

Replay();

_stateObj._inBytesUsed = _snapshotInBytesUsed;
_stateObj._inBytesPacket = _snapshotInBytesPacket;

_stateObj._messageStatus = _snapshotMessageStatus;
_stateObj._nullBitmapInfo = _snapshotNullBitmapInfo;
_stateObj._cleanupMetaData = _snapshotCleanupMetaData;
_stateObj._cleanupAltMetaDataSetArray = _snapshotCleanupAltMetaDataSetArray;

// Make sure to go through the appropriate increment/decrement methods if changing the OpenResult flag
if (!_stateObj.HasOpenResult && ((_state & SnapshottedStateFlags.OpenResult) == SnapshottedStateFlags.OpenResult))
{
_stateObj.IncrementAndObtainOpenResultCount(_stateObj._executedUnderTransaction);
}
else if (_stateObj.HasOpenResult && ((_state & SnapshottedStateFlags.OpenResult) != SnapshottedStateFlags.OpenResult))
{
_stateObj.DecrementOpenResultCount();
}
_stateObj._snapshottedState = _state;

// Reset partially read state (these only need to be maintained if doing async without snapshot)
_stateObj._bTmpRead = 0;
_stateObj._partialHeaderBytesRead = 0;

// reset plp state
_stateObj._longlen = _plpData?.SnapshotLongLen ?? 0;
_stateObj._longlenleft = _plpData?.SnapshotLongLenLeft ?? 0;

_stateObj._snapshotReplay = true;

_stateObj.AssertValidState();
}

internal void Clear()
{
PacketData packet = _snapshotInBuffList;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2480,7 +2480,7 @@ internal bool TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataRead
{
if (token == TdsEnums.SQLERROR)
{
stateObj._errorTokenReceived = true; // Keep track of the fact error token was received - for Done processing.
stateObj.HasReceivedError = true; // Keep track of the fact error token was received - for Done processing.
}

SqlError error;
Expand Down Expand Up @@ -3538,13 +3538,13 @@ private bool TryProcessDone(SqlCommand cmd, SqlDataReader reader, ref RunBehavio
}

// Skip the bogus DONE counts sent by the server
if (stateObj._receivedColMetaData || (curCmd != TdsEnums.SELECT))
if (stateObj.HasReceivedColumnMetadata || (curCmd != TdsEnums.SELECT))
{
cmd.OnStatementCompleted(count);
}
}

stateObj._receivedColMetaData = false;
stateObj.HasReceivedColumnMetadata = false;

// Surface exception for DONE_ERROR in the case we did not receive an error token
// in the stream, but an error occurred. In these cases, we throw a general server error. The
Expand All @@ -3553,7 +3553,7 @@ private bool TryProcessDone(SqlCommand cmd, SqlDataReader reader, ref RunBehavio
// the server has reached its max connection limit. Bottom line, we need to throw general
// error in the cases where we did not receive a error token along with the DONE_ERROR.
if ((TdsEnums.DONE_ERROR == (TdsEnums.DONE_ERROR & status)) && stateObj.ErrorCount == 0 &&
stateObj._errorTokenReceived == false && (RunBehavior.Clean != (RunBehavior.Clean & run)))
stateObj.HasReceivedError == false && (RunBehavior.Clean != (RunBehavior.Clean & run)))
{
stateObj.AddError(new SqlError(0, 0, TdsEnums.MIN_ERROR_CLASS, _server, SQLMessage.SevereError(), "", 0));

Expand Down Expand Up @@ -3587,7 +3587,7 @@ private bool TryProcessDone(SqlCommand cmd, SqlDataReader reader, ref RunBehavio
// stop if the DONE_MORE bit isn't set (see above for attention handling)
if (TdsEnums.DONE_MORE != (status & TdsEnums.DONE_MORE))
{
stateObj._errorTokenReceived = false;
stateObj.HasReceivedError = false;
if (stateObj._inBytesUsed >= stateObj._inBytesRead)
{
stateObj.HasPendingData = false;
Expand All @@ -3597,7 +3597,7 @@ private bool TryProcessDone(SqlCommand cmd, SqlDataReader reader, ref RunBehavio
// _pendingData set by e.g. 'TdsExecuteSQLBatch'
// _hasOpenResult always set to true by 'WriteMarsHeader'
//
if (!stateObj.HasPendingData && stateObj._hasOpenResult)
if (!stateObj.HasPendingData && stateObj.HasOpenResult)
{
/*
Debug.Assert(!((sqlTransaction != null && _distributedTransaction != null) ||
Expand Down Expand Up @@ -5743,7 +5743,7 @@ private bool TryCommonProcessMetaData(TdsParserStateObject stateObj, _SqlMetaDat

// We get too many DONE COUNTs from the server, causing too meany StatementCompleted event firings.
// We only need to fire this event when we actually have a meta data stream with 0 or more rows.
stateObj._receivedColMetaData = true;
stateObj.HasReceivedColumnMetadata = true;
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ internal partial class TdsParserStateObject
{
private SNIHandle _sessionHandle = null; // the SNI handle we're to work on

private bool _pendingData = false;
internal bool _errorTokenReceived = false; // Keep track of whether an error was received for the result.
// This is reset upon each done token - there can be
// SNI variables // multiple resultsets in one batch.
private SNIPacket _sniPacket = null; // Will have to re-vamp this for MARS
internal SNIPacket _sniAsyncAttnPacket = null; // Packet to use to send Attn
Expand All @@ -32,25 +29,18 @@ internal partial class TdsParserStateObject
// Async variables
private GCHandle _gcHandle; // keeps this object alive until we're closed.

// Timeout variables
private bool _attentionReceived = false; // NOTE: Received is not volatile as it is only ever accessed\modified by TryRun its callees (i.e. single threaded access)

// This variable is used to prevent sending an attention by another thread that is not the
// current owner of the stateObj. I currently do not know how this can happen. Mark added
// the code but does not remember either. At some point, we need to research killing this
// logic.
private volatile int _allowObjectID;

internal bool _hasOpenResult = false;

// Used for blanking out password in trace.
internal int _tracePasswordOffset = 0;
internal int _tracePasswordLength = 0;
internal int _traceChangePasswordOffset = 0;
internal int _traceChangePasswordLength = 0;

internal bool _receivedColMetaData; // Used to keep track of when to fire StatementCompleted event.

//////////////////
// Constructors //
//////////////////
Expand Down Expand Up @@ -100,18 +90,6 @@ internal SNIHandle Handle
return _sessionHandle;
}
}

internal bool HasOpenResult
{
get => _hasOpenResult;
set => _hasOpenResult = value;
}

internal bool HasPendingData
{
get => _pendingData;
set => _pendingData = value;
}

internal uint Status
{
Expand Down Expand Up @@ -394,12 +372,6 @@ internal void StartSession(int objectID)
_allowObjectID = objectID;
}

internal bool HasReceivedAttention
{
get => _attentionReceived;
set => _attentionReceived = value;
}

///////////////////////////////////////
// Buffer read methods - data values //
///////////////////////////////////////
Expand Down Expand Up @@ -3230,11 +3202,6 @@ sealed partial class StateSnapshot
{
private List<PacketData> _snapshotInBuffs;

private bool _snapshotPendingData = false;
private bool _snapshotErrorTokenReceived = false;
private bool _snapshotHasOpenResult = false;
private bool _snapshotReceivedColumnMetadata = false;
private bool _snapshotAttentionReceived;

public StateSnapshot()
{
Expand Down Expand Up @@ -3308,8 +3275,6 @@ internal void Snap(TdsParserStateObject state)
_snapshotInBuffCurrent = 0;
_snapshotInBytesUsed = _stateObj._inBytesUsed;
_snapshotInBytesPacket = _stateObj._inBytesPacket;
_snapshotPendingData = _stateObj._pendingData;
_snapshotErrorTokenReceived = _stateObj._errorTokenReceived;
_snapshotMessageStatus = _stateObj._messageStatus;
// _nullBitmapInfo must be cloned before it is updated
_snapshotNullBitmapInfo = _stateObj._nullBitmapInfo;
Expand All @@ -3320,9 +3285,8 @@ internal void Snap(TdsParserStateObject state)
_snapshotCleanupMetaData = _stateObj._cleanupMetaData;
// _cleanupAltMetaDataSetArray must be cloned bofore it is updated
_snapshotCleanupAltMetaDataSetArray = _stateObj._cleanupAltMetaDataSetArray;
_snapshotHasOpenResult = _stateObj._hasOpenResult;
_snapshotReceivedColumnMetadata = _stateObj._receivedColMetaData;
_snapshotAttentionReceived = _stateObj._attentionReceived;

_state = _stateObj._snapshottedState;
#if DEBUG
_rollingPend = 0;
_rollingPendCount = 0;
Expand All @@ -3334,59 +3298,10 @@ internal void Snap(TdsParserStateObject state)
PushBuffer(_stateObj._inBuff, _stateObj._inBytesRead);
}

internal void ResetSnapshotState()
{
// go back to the beginning
_snapshotInBuffCurrent = 0;

Replay();

_stateObj._inBytesUsed = _snapshotInBytesUsed;
_stateObj._inBytesPacket = _snapshotInBytesPacket;
_stateObj._pendingData = _snapshotPendingData;
_stateObj._errorTokenReceived = _snapshotErrorTokenReceived;
_stateObj._messageStatus = _snapshotMessageStatus;
_stateObj._nullBitmapInfo = _snapshotNullBitmapInfo;
_stateObj._cleanupMetaData = _snapshotCleanupMetaData;
_stateObj._cleanupAltMetaDataSetArray = _snapshotCleanupAltMetaDataSetArray;

// Make sure to go through the appropriate increment/decrement methods if changing HasOpenResult
if (!_stateObj._hasOpenResult && _snapshotHasOpenResult)
{
_stateObj.IncrementAndObtainOpenResultCount(_stateObj._executedUnderTransaction);
}
else if (_stateObj._hasOpenResult && !_snapshotHasOpenResult)
{
_stateObj.DecrementOpenResultCount();
}
//else _stateObj._hasOpenResult is already == _snapshotHasOpenResult

_stateObj._receivedColMetaData = _snapshotReceivedColumnMetadata;
_stateObj._attentionReceived = _snapshotAttentionReceived;

// Reset partially read state (these only need to be maintained if doing async without snapshot)
_stateObj._bTmpRead = 0;
_stateObj._partialHeaderBytesRead = 0;

// reset plp state
_stateObj._longlen = _plpData?.SnapshotLongLen ?? 0;
_stateObj._longlenleft = _plpData?.SnapshotLongLenLeft ?? 0;

_stateObj._snapshotReplay = true;

_stateObj.AssertValidState();
}

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

_snapshotPendingData = false;
_snapshotErrorTokenReceived = false;
_snapshotHasOpenResult = false;
_snapshotReceivedColumnMetadata = false;
_snapshotAttentionReceived = false;

ClearCore();
}
}
Expand Down

0 comments on commit cc5f05a

Please sign in to comment.