/// <summary> /// Constructor /// </summary> /// <param name="connection">MARS connection</param> /// <param name="sessionId">MARS session ID</param> /// <param name="callbackObject">Callback object</param> /// <param name="async">true if connection is asynchronous</param> public SNIMarsHandle(SNIMarsConnection connection, ushort sessionId, TdsParserStateObject callbackObject, out SNIError sniError) { _sessionId = sessionId; _connection = connection; _callbackObject = callbackObject; sniError = SendControlPacket(SNISMUXFlags.SMUX_SYN, true); }
protected override void CreateSessionHandle(TdsParserStateObject physicalConnection, bool async) { Debug.Assert(physicalConnection is TdsParserStateObjectManaged, "Expected a stateObject of type " + this.GetType()); TdsParserStateObjectManaged managedSNIObject = physicalConnection as TdsParserStateObjectManaged; _sessionHandle = SNIProxy.Singleton.CreateMarsHandle(this, managedSNIObject.Handle, _outBuff.Length, async); }
internal void Deactivate() { IntPtr ptr; Bid.ScopeEnter(out ptr, "<sc.TdsParserSessionPool.Deactivate|ADV> %d# deactivating cachedCount=%d\n", this.ObjectID, this._cachedCount); try { lock (this._cache) { for (int i = this._cache.Count - 1; i >= 0; i--) { TdsParserStateObject session = this._cache[i]; if ((session != null) && session.IsOrphaned) { if (Bid.AdvancedOn) { Bid.Trace("<sc.TdsParserSessionPool.Deactivate|ADV> %d# reclaiming session %d\n", this.ObjectID, session.ObjectID); } this.PutSession(session); } } } } finally { Bid.ScopeLeave(ref ptr); } }
internal void PutSession(TdsParserStateObject session) { bool flag2 = session.Deactivate(); if (!this.IsDisposed) { if (flag2 && (this._cachedCount < 10)) { if (Bid.AdvancedOn) { Bid.Trace("<sc.TdsParserSessionPool.PutSession|ADV> %d# keeping session %d cachedCount=%d\n", this.ObjectID, session.ObjectID, this._cachedCount); } this._freeStack.SynchronizedPush(session); } else { if (Bid.AdvancedOn) { Bid.Trace("<sc.TdsParserSessionPool.PutSession|ADV> %d# disposing session %d cachedCount=%d\n", this.ObjectID, session.ObjectID, this._cachedCount); } lock (this._cache) { this._cache.Remove(session); this._cachedCount = this._cache.Count; } session.Dispose(); } } }
internal void Deactivate() { // When being deactivated, we check all the sessions in the // cache to make sure they're cleaned up and then we dispose of // sessions that are past what we want to keep around. using (TryEventScope.Create("<sc.TdsParserSessionPool.Deactivate|ADV> {0} deactivating cachedCount={1}", ObjectID, _cachedCount)) { lock (_cache) { // NOTE: The PutSession call below may choose to remove the // session from the cache, which will throw off our // enumerator. We avoid that by simply indexing backward // through the array. for (int i = _cache.Count - 1; i >= 0; i--) { TdsParserStateObject session = _cache[i]; if (null != session) { if (session.IsOrphaned) { // TODO: consider adding a performance counter for the number of sessions we reclaim SqlClientEventSource.Log.TryAdvancedTraceEvent("<sc.TdsParserSessionPool.Deactivate|ADV> {0} reclaiming session {1}", ObjectID, session.ObjectID); PutSession(session); } } } // TODO: re-enable this assert when the connection isn't doomed. //Debug.Assert (_cachedCount < MaxInactiveCount, "non-orphaned connection past initial allocation?"); } } }
internal SqlCachedBuffer(SqlMetaDataPriv metadata, TdsParser parser, TdsParserStateObject stateObj) { int len = 0; this._cachedBytes = new ArrayList(); ulong num = parser.PlpBytesLeft(stateObj); do { if (num == 0L) { return; } do { len = (num > 0x800L) ? 0x800 : ((int)num); byte[] buff = new byte[len]; len = stateObj.ReadPlpBytes(ref buff, 0, len); if (this._cachedBytes.Count == 0) { this.AddByteOrderMark(buff); } this._cachedBytes.Add(buff); num -= len; }while (num > 0L); num = parser.PlpBytesLeft(stateObj); }while (num > 0L); }
protected override void CreateSessionHandle(TdsParserStateObject physicalConnection, bool async) { Debug.Assert(physicalConnection is TdsParserStateObjectManaged, "Expected a stateObject of type " + this.GetType()); TdsParserStateObjectManaged managedSNIObject = physicalConnection as TdsParserStateObjectManaged; _sessionHandle = managedSNIObject.CreateMarsSession(this, async); }
internal void PutSession(TdsParserStateObject session) { Debug.Assert(null != session, "null session?"); bool okToReuse; _parser.Connection._parserLock.Wait(canReleaseFromAnyThread: false); try { okToReuse = session.Deactivate(); } finally { _parser.Connection._parserLock.Release(); } bool disposeSession = false; lock (_cache) { if (IsDisposed) { // We're diposed - just clean out the session Debug.Assert(_cache.Count == 0, "SessionPool is disposed, but there are still sessions in the cache?"); disposeSession = true; } else if ((okToReuse) && (_freeStateObjectCount < MaxInactiveCount)) { // Session is good to re-use and our cache has space Debug.Assert(!session._pendingData, "pending data on a pooled session?"); _freeStateObjects[_freeStateObjectCount] = session; _freeStateObjectCount++; } else { // Either the session is bad, or we have no cache space - so dispose the session and remove it bool removed = _cache.Remove(session); Debug.Assert(removed, "session not in pool?"); disposeSession = true; } session.RemoveOwner(); } if (disposeSession) { _parser.Connection._parserLock.Wait(canReleaseFromAnyThread: false); try { session.Dispose(); } finally { _parser.Connection._parserLock.Release(); } } }
/// <summary> /// Enables MARS for a TdsParserStateObject and returns its new handle. /// </summary> public static SNIMarsHandle EnableMars(TdsParserStateObject stateObject, out SNIError sniError) { Debug.Assert(!(stateObject.Handle is SNIMarsHandle), "Cannot enable MARS on a SNIMarsHandle"); SNIMarsConnection marsConnection = new SNIMarsConnection(stateObject.Handle); marsConnection.StartReceive(); return(marsConnection.CreateSession(stateObject, out sniError)); }
internal TdsValueSetter(TdsParserStateObject stateObj, SmiMetaData md) { this._stateObj = stateObj; this._metaData = md; this._isPlp = MetaDataUtilsSmi.IsPlpFormat(md); this._plpUnknownSent = false; this._encoder = null; }
protected override void CreateSessionHandle(TdsParserStateObject physicalConnection, bool async) { Debug.Assert(physicalConnection is TdsParserStateObjectNative, "Expected a stateObject of type " + this.GetType()); TdsParserStateObjectNative nativeSNIObject = physicalConnection as TdsParserStateObjectNative; SNINativeMethodWrapper.ConsumerInfo myInfo = CreateConsumerInfo(async); _sessionHandle = new SNIHandle(myInfo, nativeSNIObject.Handle); }
internal void SynchronizedPush(TdsParserStateObject value) { lock (this) { value.NextPooledObject = this._stack; this._stack = value; } }
protected override void CreateSessionHandle(TdsParserStateObject physicalConnection, bool async) { Debug.Assert(physicalConnection is TdsParserStateObjectManaged, "Expected a stateObject of type " + GetType()); TdsParserStateObjectManaged managedSNIObject = physicalConnection as TdsParserStateObjectManaged; _sessionHandle = managedSNIObject.CreateMarsSession(this, async); SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.CreateSessionHandle | Info | State Object Id {0}, Session Id {1}", _objectID, _sessionHandle?.ConnectionId); }
internal TdsRecordBufferSetter(TdsParserStateObject stateObj, SmiMetaData md) { this._fieldSetters = new TdsValueSetter[md.FieldMetaData.Count]; for (int i = 0; i < md.FieldMetaData.Count; i++) { this._fieldSetters[i] = new TdsValueSetter(stateObj, md.FieldMetaData[i]); } this._stateObj = stateObj; this._metaData = md; }
internal SqlCommand FindLiveCommand(TdsParserStateObject stateObj) { SqlCommand command = null; SqlReferenceCollection referenceCollection = (SqlReferenceCollection)ReferenceCollection; if (null != referenceCollection) { command = referenceCollection.FindLiveCommand(stateObj); } return command; }
public SNIMarsHandle CreateSession(TdsParserStateObject callbackObject, out SNIError sniError) { lock (this) { ushort sessionId = _nextSessionId++; SNIMarsHandle handle = new SNIMarsHandle(this, sessionId, callbackObject, out sniError); _sessions.Add(sessionId, handle); return(handle); } }
private int _currentOffset; // for chunking, verify that caller is using correct offsets #endif #endregion #region Exposed Construct/factory methods internal TdsValueSetter(TdsParserStateObject stateObj, SmiMetaData md) { _stateObj = stateObj; _metaData = md; _isPlp = MetaDataUtilsSmi.IsPlpFormat(md); _plpUnknownSent = false; _encoder = null; #if DEBUG _currentOffset = 0; #endif }
internal TdsParserStateObject CreateSessionObject(TdsParser tdsParser, TdsParserStateObject _pMarsPhysicalConObj, bool v) { if (TdsParserStateObjectFactory.UseManagedSNI) { return(new TdsParserStateObjectManaged(tdsParser, _pMarsPhysicalConObj, true)); } else { return(new TdsParserStateObjectNative(tdsParser, _pMarsPhysicalConObj, true)); } }
private static void WriteDispatcher(IntPtr key, IntPtr packet, uint error) { if (IntPtr.Zero != key) { GCHandle handle = (GCHandle)key; TdsParserStateObject target = (TdsParserStateObject)handle.Target; if (target != null) { target.WriteAsyncCallback(IntPtr.Zero, packet, error); } } }
protected override void CreateSessionHandle(TdsParserStateObject physicalConnection, bool async) { Debug.Assert(physicalConnection is TdsParserStateObjectNative, "Expected a stateObject of type " + this.GetType()); TdsParserStateObjectNative nativeSNIObject = physicalConnection as TdsParserStateObjectNative; SNINativeMethodWrapper.ConsumerInfo myInfo = CreateConsumerInfo(async); SQLDNSInfo cachedDNSInfo; bool ret = SQLFallbackDNSCache.Instance.GetDNSInfo(_parser.FQDNforDNSCahce, out cachedDNSInfo); _sessionHandle = new SNIHandle(myInfo, nativeSNIObject.Handle, cachedDNSInfo); }
// Reads off from the network buffer and caches bytes. Only reads one column value in the current row. static internal bool TryCreate(SqlMetaDataPriv metadata, TdsParser parser, TdsParserStateObject stateObj, out SqlCachedBuffer buffer) { int cb = 0; ulong plplength; byte[] byteArr; List <byte[]> cachedBytes = new List <byte[]>(); buffer = null; // the very first length is already read. if (!parser.TryPlpBytesLeft(stateObj, out plplength)) { return(false); } // For now we only handle Plp data from the parser directly. Debug.Assert(metadata.metaType.IsPlp, "SqlCachedBuffer call on a non-plp data"); do { if (plplength == 0) { break; } do { cb = (plplength > (ulong)_maxChunkSize) ? _maxChunkSize : (int)plplength; byteArr = new byte[cb]; if (!stateObj.TryReadPlpBytes(ref byteArr, 0, cb, out cb)) { return(false); } Debug.Assert(cb == byteArr.Length); if (cachedBytes.Count == 0) { // Add the Byte order mark if needed if we read the first array AddByteOrderMark(byteArr, cachedBytes); } cachedBytes.Add(byteArr); plplength -= (ulong)cb; } while (plplength > 0); if (!parser.TryPlpBytesLeft(stateObj, out plplength)) { return(false); } } while (plplength > 0); Debug.Assert(stateObj._longlen == 0 && stateObj._longlenleft == 0); buffer = new SqlCachedBuffer(cachedBytes); return(true); }
private int _currentField; // validate that caller sets columns in correct order. #endif #endregion #region Exposed Construct and control methods/properties internal TdsRecordBufferSetter(TdsParserStateObject stateObj, SmiMetaData md) { Debug.Assert(SqlDbType.Structured == md.SqlDbType, "Unsupported SqlDbType: " + md.SqlDbType); _fieldSetters = new TdsValueSetter[md.FieldMetaData.Count]; for (int i = 0; i < md.FieldMetaData.Count; i++) { _fieldSetters[i] = new TdsValueSetter(stateObj, md.FieldMetaData[i]); } _stateObj = stateObj; _metaData = md; #if DEBUG _currentField = ReadyForToken; #endif }
// This is called from a ThreadAbort - ensure that it can be run from a CER Catch internal void BestEffortCleanup() { for (int i = 0; i < _cache.Count; i++) { TdsParserStateObject session = _cache[i]; if (null != session) { var sessionHandle = session.Handle; if (sessionHandle != null) { sessionHandle.Dispose(); } } } }
internal TdsParserStateObject SynchronizedPop() { TdsParserStateObject obj2; lock (this) { obj2 = this._stack; if (obj2 != null) { this._stack = obj2.NextPooledObject; obj2.NextPooledObject = null; } } return(obj2); }
internal TdsParserStateObject CreateSession() { TdsParserStateObject item = this._parser.CreateSession(); lock (this._cache) { if (Bid.AdvancedOn) { Bid.Trace("<sc.TdsParserSessionPool.CreateSession|ADV> %d# adding session %d to pool\n", this.ObjectID, item.ObjectID); } this._cache.Add(item); this._cachedCount = this._cache.Count; } return(item); }
internal TdsParserStateObject GetSession(object owner) { TdsParserStateObject obj2 = this._freeStack.SynchronizedPop(); if (obj2 == null) { obj2 = this.CreateSession(); } obj2.Activate(owner); if (Bid.AdvancedOn) { Bid.Trace("<sc.TdsParserSessionPool.GetSession|ADV> %d# using session %d\n", this.ObjectID, obj2.ObjectID); } return(obj2); }
internal void Deactivate() { // When being deactivated, we check all the sessions in the // cache to make sure they're cleaned up and then we dispose of // sessions that are past what we want to keep around. IntPtr hscp; Bid.ScopeEnter(out hscp, "<sc.TdsParserSessionPool.Deactivate|ADV> %d# deactivating cachedCount=%d\n", ObjectID, _cachedCount); try { lock (_cache) { // NOTE: The PutSession call below may choose to remove the // session from the cache, which will throw off our // enumerator. We avoid that by simply indexing backward // through the array. for (int i = _cache.Count - 1; i >= 0; i--) { TdsParserStateObject session = _cache[i]; if (null != session) { if (session.IsOrphaned) { // TODO: consider adding a performance counter for the number of sessions we reclaim if (Bid.AdvancedOn) { Bid.Trace("<sc.TdsParserSessionPool.Deactivate|ADV> %d# reclaiming session %d\n", ObjectID, session.ObjectID); } PutSession(session); } } } // TODO: re-enable this assert when the connection isn't doomed. //Debug.Assert (_cachedCount < MaxInactiveCount, "non-orphaned connection past initial allocation?"); } } finally { Bid.ScopeLeave(ref hscp); } }
internal void PutSession(TdsParserStateObject session) { Debug.Assert(null != session, "null session?"); //Debug.Assert(null != session.Owner, "session without owner?"); bool okToReuse = session.Deactivate(); lock (_cache) { if (IsDisposed) { // We're diposed - 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 if (Bid.AdvancedOn) { Bid.Trace("<sc.TdsParserSessionPool.PutSession|ADV> %d# keeping session %d cachedCount=%d\n", ObjectID, session.ObjectID, _cachedCount); } Debug.Assert(!session._pendingData, "pending data on a pooled session?"); _freeStateObjects[_freeStateObjectCount] = session; _freeStateObjectCount++; } else { // Either the session is bad, or we have no cache space - so dispose the session and remove it if (Bid.AdvancedOn) { Bid.Trace("<sc.TdsParserSessionPool.PutSession|ADV> %d# disposing session %d cachedCount=%d\n", ObjectID, session.ObjectID, _cachedCount); } bool removed = _cache.Remove(session); Debug.Assert(removed, "session not in pool?"); _cachedCount = _cache.Count; session.Dispose(); } session.RemoveOwner(); } }
internal void Deactivate() { // When being deactivated, we check all the sessions in the // cache to make sure they're cleaned up and then we dispose of // sessions that are past what we want to keep around. IntPtr hscp; Bid.ScopeEnter(out hscp, "<sc.TdsParserSessionPool.Deactivate|ADV> %d# deactivating cachedCount=%d\n", ObjectID, _cachedCount); try { lock (_cache) { // NOTE: The PutSession call below may choose to remove the // session from the cache, which will throw off our // enumerator. We avoid that by simply indexing backward // through the array. for (int i = _cache.Count - 1; i >= 0; i--) { TdsParserStateObject session = _cache[i]; if (null != session) { if (session.IsOrphaned) { // if (Bid.AdvancedOn) { Bid.Trace("<sc.TdsParserSessionPool.Deactivate|ADV> %d# reclaiming session %d\n", ObjectID, session.ObjectID); } PutSession(session); } } } // } } finally { Bid.ScopeLeave(ref hscp); } }
static private void ReadDispatcher(IntPtr key, IntPtr packet, UInt32 error) { // This is the app-domain dispatcher for all async read callbacks, It // simply gets the state object from the key that it is passed, and // calls the state object's read callback. Debug.Assert(IntPtr.Zero != key, "no key passed to read callback dispatcher?"); if (IntPtr.Zero != key) { // NOTE: we will get a null ref here if we don't get a key that // contains a GCHandle to TDSParserStateObject; that is // very bad, and we want that to occur so we can catch it. GCHandle gcHandle = (GCHandle)key; TdsParserStateObject stateObj = (TdsParserStateObject)gcHandle.Target; if (null != stateObj) { stateObj.ReadAsyncCallback(IntPtr.Zero, packet, error); } } }