Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge to shared - TdsParserSessionPool #1595

Merged
merged 9 commits into from
Oct 5, 2022
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,9 @@
<Compile Include="..\..\src\Microsoft\Data\SqlClient\TdsRecordBufferSetter.cs">
<Link>Microsoft\Data\SqlClient\TdsRecordBufferSetter.cs</Link>
</Compile>
<Compile Include="..\..\src\Microsoft\Data\SqlClient\TdsParserSessionPool.cs">
<Link>Microsoft\Data\SqlClient\TdsParserSessionPool.cs</Link>
</Compile>
<Compile Include="..\..\src\Microsoft\Data\SqlClient\TdsValueSetter.cs">
<Link>Microsoft\Data\SqlClient\TdsValueSetter.cs</Link>
</Compile>
Expand Down Expand Up @@ -641,7 +644,6 @@
<Compile Include="Microsoft\Data\SqlClient\TdsParser.cs" />
<Compile Include="Microsoft\Data\SqlClient\TdsParser.RegisterEncoding.cs" />
<Compile Include="Microsoft\Data\SqlClient\TdsParserHelperClasses.cs" />
<Compile Include="Microsoft\Data\SqlClient\TdsParserSessionPool.cs" />
<Compile Include="Microsoft\Data\SqlClient\TdsParserStateObject.cs" />
<Compile Include="Microsoft\Data\SqlClient\TdsParserStateObjectManaged.cs" />
</ItemGroup>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,9 @@
<Compile Include="..\..\src\Microsoft\Data\SqlClient\TdsRecordBufferSetter.cs">
<Link>Microsoft\Data\SqlClient\TdsRecordBufferSetter.cs</Link>
</Compile>
<Compile Include="..\..\src\Microsoft\Data\SqlClient\TdsParserSessionPool.cs">
<Link>Microsoft\Data\SqlClient\TdsParserSessionPool.cs</Link>
</Compile>
<Compile Include="..\..\src\Microsoft\Data\SqlClient\TdsValueSetter.cs">
<Link>Microsoft\Data\SqlClient\TdsValueSetter.cs</Link>
</Compile>
Expand Down Expand Up @@ -649,7 +652,6 @@
<Compile Include="Microsoft\Data\SqlClient\TdsParser.cs" />
<Compile Include="Microsoft\Data\SqlClient\TdsParserHelperClasses.cs" />
<Compile Include="Microsoft\Data\SqlClient\TdsParserSafeHandles.cs" />
<Compile Include="Microsoft\Data\SqlClient\TdsParserSessionPool.cs" />
<Compile Include="Microsoft\Data\SqlClient\TdsParserStateObject.cs" />
<Compile Include="Microsoft\Data\SqlTypes\SqlFileStream.cs" />
<Compile Include="Microsoft\Data\SqlTypes\SqlStreamChars.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ internal class TdsParserSessionPool
// NOTE: This is a very simplistic, lightweight pooler. It wasn't
// intended to handle huge number of items, just to keep track
// of the session objects to ensure that they're cleaned up in
// a timely manner, to avoid holding on to an unacceptible
// a timely manner, to avoid holding on to an unacceptable
// amount of server-side resources in the event that consumers
// let their data readers be GC'd, instead of explicitly
// closing or disposing of them

private const int MaxInactiveCount = 10; // pick something, preferably small...

private static int _objectTypeCount; // EventSource Counter
private readonly int _objectID = System.Threading.Interlocked.Increment(ref _objectTypeCount);
private static int s_objectTypeCount; // EventSource Counter
private readonly int _objectID = System.Threading.Interlocked.Increment(ref s_objectTypeCount);

private readonly TdsParser _parser; // parser that owns us
private readonly List<TdsParserStateObject> _cache; // collection of all known sessions
Expand Down Expand Up @@ -89,6 +89,7 @@ internal void Deactivate()
}
}

#if NETFRAMEWORK
lcheunglci marked this conversation as resolved.
Show resolved Hide resolved
// This is called from a ThreadAbort - ensure that it can be run from a CER Catch
internal void BestEffortCleanup()
{
Expand All @@ -97,14 +98,15 @@ internal void BestEffortCleanup()
TdsParserStateObject session = _cache[i];
if (null != session)
{
var sessionHandle = session.Handle;
SNIHandle sessionHandle = session.Handle;
if (sessionHandle != null)
{
sessionHandle.Dispose();
}
}
}
}
#endif

internal void Dispose()
{
Expand Down Expand Up @@ -140,7 +142,6 @@ internal void Dispose()
}
_cache.Clear();
_cachedCount = 0;

// Any active sessions will take care of themselves
// (It's too dangerous to dispose them, as this can cause AVs)
}
Expand Down Expand Up @@ -175,6 +176,7 @@ internal TdsParserStateObject GetSession(object owner)

session.Activate(owner);
}

SqlClientEventSource.Log.TryAdvancedTraceEvent("<sc.TdsParserSessionPool.GetSession|ADV> {0} using session {1}", ObjectID, session.ObjectID);
return session;
}
Expand All @@ -190,16 +192,20 @@ internal void PutSession(TdsParserStateObject session)
{
if (IsDisposed)
{
// We're diposed - just clean out the session
// We're disposed - just clean out the session
Debug.Assert(_cachedCount == 0, "SessionPool is disposed, but there are still sessions in the cache?");
session.Dispose();
}
else if ((okToReuse) && (_freeStateObjectCount < MaxInactiveCount))
{
// Session is good to re-use and our cache has space
SqlClientEventSource.Log.TryAdvancedTraceEvent("<sc.TdsParserSessionPool.PutSession|ADV> {0} keeping session {1} cachedCount={2}", ObjectID, session.ObjectID, _cachedCount);
// TODO: To avoid merge conflict with TdsParserStateObject in PR# 1520, i.e. it'll be merged in the common code base, we can clean this up in a later PR.
#if NETFRAMEWORK
Debug.Assert(!session._pendingData, "pending data on a pooled session?");

#else
Debug.Assert(!session.HasPendingData, "pending data on a pooled session?");
#endif
lcheunglci marked this conversation as resolved.
Show resolved Hide resolved
_freeStateObjects[_freeStateObjectCount] = session;
_freeStateObjectCount++;
}
Expand All @@ -218,15 +224,6 @@ internal void PutSession(TdsParserStateObject session)
}
}

internal string TraceString()
{
return String.Format(/*IFormatProvider*/ null,
"(ObjID={0}, free={1}, cached={2}, total={3})",
_objectID,
null == _freeStateObjects ? "(null)" : _freeStateObjectCount.ToString((IFormatProvider)null),
_cachedCount,
_cache.Count);
}

internal int ActiveSessionsCount
lcheunglci marked this conversation as resolved.
Show resolved Hide resolved
{
Expand All @@ -235,6 +232,16 @@ internal int ActiveSessionsCount
return _cachedCount - _freeStateObjectCount;
}
}

internal string TraceString()
{
return string.Format(/*IFormatProvider*/ null,
"(ObjID={0}, free={1}, cached={2}, total={3})",
_objectID,
null == _freeStateObjects ? "(null)" : _freeStateObjectCount.ToString((IFormatProvider)null),
_cachedCount,
_cache.Count);
}
}
}

Expand Down