internal DbConnectionPool GetConnectionPool(DbConnectionFactory connectionFactory)
 {
     object obj2 = null;
     if (this._poolGroupOptions != null)
     {
         DbConnectionPoolIdentity noIdentity = DbConnectionPoolIdentity.NoIdentity;
         if (this._poolGroupOptions.PoolByIdentity)
         {
             noIdentity = DbConnectionPoolIdentity.GetCurrent();
             if (noIdentity.IsRestricted)
             {
                 noIdentity = null;
             }
         }
         if (noIdentity != null)
         {
             obj2 = this._poolCollection[noIdentity];
             if (obj2 == null)
             {
                 DbConnectionPoolProviderInfo connectionPoolProviderInfo = connectionFactory.CreateConnectionPoolProviderInfo(this.ConnectionOptions);
                 DbConnectionPool pool = new DbConnectionPool(connectionFactory, this, noIdentity, connectionPoolProviderInfo);
                 lock (this)
                 {
                     HybridDictionary dictionary = this._poolCollection;
                     obj2 = dictionary[noIdentity];
                     if ((obj2 == null) && this.MarkPoolGroupAsActive())
                     {
                         pool.Startup();
                         HybridDictionary dictionary2 = new HybridDictionary(1 + dictionary.Count, false);
                         foreach (DictionaryEntry entry in dictionary)
                         {
                             dictionary2.Add(entry.Key, entry.Value);
                         }
                         dictionary2.Add(noIdentity, pool);
                         connectionFactory.PerformanceCounters.NumberOfActiveConnectionPools.Increment();
                         this._poolCollection = dictionary2;
                         this._poolCount = dictionary2.Count;
                         obj2 = pool;
                         pool = null;
                     }
                 }
                 if (pool != null)
                 {
                     pool.Shutdown();
                 }
             }
         }
     }
     if (obj2 == null)
     {
         lock (this)
         {
             this.MarkPoolGroupAsActive();
         }
     }
     return (DbConnectionPool) obj2;
 }
 internal override void OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
 {
     if (connectionFactory.SetInnerConnectionFrom(outerConnection, DbConnectionClosedConnecting.SingletonInstance, this))
     {
         DbConnectionInternal to = null;
         try
         {
             connectionFactory.PermissionDemand(outerConnection);
             to = connectionFactory.GetConnection(outerConnection);
         }
         catch
         {
             connectionFactory.SetInnerConnectionTo(outerConnection, this);
             throw;
         }
         if (to == null)
         {
             connectionFactory.SetInnerConnectionTo(outerConnection, this);
             throw ADP.InternalConnectionError(ADP.ConnectionError.GetConnectionReturnsNull);
         }
         connectionFactory.SetInnerConnectionEvent(outerConnection, to);
     }
 }
 /// <devdoc>The default implementation is for the open connection objects, and
 /// it simply throws.  Our private closed-state connection objects
 /// override this and do the correct thing.</devdoc>
 // User code should either override DbConnectionInternal.Activate when it comes out of the pool
 // or override DbConnectionFactory.CreateConnection when the connection is created for non-pooled connections
 internal virtual bool TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource<DbConnectionInternal> retry, DbConnectionOptions userOptions) {
     throw ADP.ConnectionAlreadyOpen(State);
 }
        virtual protected internal DataTable GetSchema(DbConnectionFactory factory, DbConnectionPoolGroup poolGroup, DbConnection outerConnection, string collectionName, string[] restrictions){
            Debug.Assert(outerConnection != null,"outerConnection may not be null.");

            DbMetaDataFactory metaDataFactory = factory.GetMetaDataFactory(poolGroup, this);
            Debug.Assert(metaDataFactory != null,"metaDataFactory may not be null.");

            return metaDataFactory.GetSchema(outerConnection, collectionName,restrictions);
        }
        internal DbConnectionPool GetConnectionPool(DbConnectionFactory connectionFactory) {
            // When this method returns null it indicates that the connection
            // factory should not use pooling.

            // We don't support connection pooling on Win9x; it lacks too
            // many of the APIs we require.
            // PoolGroupOptions will only be null when we're not supposed to pool
            // connections.
            DbConnectionPool pool = null;
            if (null != _poolGroupOptions) {
                Debug.Assert(ADP.IsWindowsNT, "should not be pooling on Win9x");

                DbConnectionPoolIdentity currentIdentity = DbConnectionPoolIdentity.NoIdentity;
                if (_poolGroupOptions.PoolByIdentity) {
                    // if we're pooling by identity (because integrated security is
                    // being used for these connections) then we need to go out and
                    // search for the connectionPool that matches the current identity.

                    currentIdentity = DbConnectionPoolIdentity.GetCurrent();

                    // If the current token is restricted in some way, then we must
                    // not attempt to pool these connections.
                    if (currentIdentity.IsRestricted) {
                        currentIdentity = null;
                    }
                }
                if (null != currentIdentity) {
                    if (!_poolCollection.TryGetValue(currentIdentity, out pool)) { // find the pool
                        DbConnectionPoolProviderInfo connectionPoolProviderInfo = connectionFactory.CreateConnectionPoolProviderInfo(this.ConnectionOptions);

                        // optimistically create pool, but its callbacks are delayed until after actual add
                        DbConnectionPool newPool = new DbConnectionPool(connectionFactory, this, currentIdentity, connectionPoolProviderInfo);

                        lock (this) {
                            // Did someone already add it to the list?
                            if (!_poolCollection.TryGetValue(currentIdentity, out pool)) {
                                if (MarkPoolGroupAsActive()) {
                                    // If we get here, we know for certain that we there isn't
                                    // a pool that matches the current identity, so we have to
                                    // add the optimistically created one
                                    newPool.Startup(); // must start pool before usage
                                    bool addResult = _poolCollection.TryAdd(currentIdentity, newPool);
                                    Debug.Assert(addResult, "No other pool with current identity should exist at this point");
#if !MOBILE
                                    connectionFactory.PerformanceCounters.NumberOfActiveConnectionPools.Increment();
#endif
                                    pool = newPool;
                                    newPool = null;
                                }
                                else {
                                    // else pool entry has been disabled so don't create new pools
                                    Debug.Assert(PoolGroupStateDisabled == _state, "state should be disabled");
                                }
                            }
                            else {
                                // else found an existing pool to use instead
                                Debug.Assert(PoolGroupStateActive == _state, "state should be active since a pool exists and lock holds");
                            }
                        }

                        if (null != newPool) {
                            // don't need to call connectionFactory.QueuePoolForRelease(newPool) because
                            // pool callbacks were delayed and no risk of connections being created
                            newPool.Shutdown();
                        }
                    }
                    // the found pool could be in any state
                }
            }

            if (null == pool) {
                lock(this) {
                    // keep the pool entry state active when not pooling
                    MarkPoolGroupAsActive();
                }
            }
            return pool;
        }
 internal virtual void CloseConnection(DbConnection owningObject, DbConnectionFactory connectionFactory)
 {
     Bid.PoolerTrace("<prov.DbConnectionInternal.CloseConnection|RES|CPOOL> %d# Closing.\n", this.ObjectID);
     if (connectionFactory.SetInnerConnectionFrom(owningObject, DbConnectionOpenBusy.SingletonInstance, this))
     {
         try
         {
             DbConnectionPool pool = this.Pool;
             Transaction enlistedTransaction = this.EnlistedTransaction;
             if (null != enlistedTransaction)
             {
                 bool flag = true;
                 try
                 {
                     flag = TransactionStatus.Active != enlistedTransaction.TransactionInformation.Status;
                 }
                 catch (TransactionException)
                 {
                 }
                 if (flag)
                 {
                     this.DetachTransaction(enlistedTransaction, true);
                 }
             }
             if (pool != null)
             {
                 pool.PutObject(this, owningObject);
             }
             else
             {
                 this.Deactivate();
                 this.PerformanceCounters.HardDisconnectsPerSecond.Increment();
                 this._owningObject.Target = null;
                 if (this.IsTransactionRoot)
                 {
                     this.SetInStasis();
                 }
                 else
                 {
                     this.PerformanceCounters.NumberOfNonPooledConnections.Decrement();
                     if (base.GetType() != typeof(SqlInternalConnectionSmi))
                     {
                         this.Dispose();
                     }
                 }
             }
         }
         finally
         {
             connectionFactory.SetInnerConnectionEvent(owningObject, DbConnectionClosedPreviouslyOpened.SingletonInstance);
         }
     }
 }
 protected internal virtual DataTable GetSchema(DbConnectionFactory factory, DbConnectionPoolGroup poolGroup, DbConnection outerConnection, string collectionName, string[] restrictions)
 {
     return factory.GetMetaDataFactory(poolGroup, this).GetSchema(outerConnection, collectionName, restrictions);
 }
 internal override void CloseConnection(DbConnection owningObject, DbConnectionFactory connectionFactory) {
     // not much to do here...
 }
Example #9
0
        internal DbConnectionPool?GetConnectionPool(DbConnectionFactory connectionFactory)
        {
            // When this method returns null it indicates that the connection
            // factory should not use pooling.

            // We don't support connection pooling on Win9x; it lacks too
            // many of the APIs we require.
            // PoolGroupOptions will only be null when we're not supposed to pool
            // connections.
            DbConnectionPool?pool = null;

            if (null != _poolGroupOptions)
            {
                Debug.Assert(ADP.IsWindowsNT, "should not be pooling on Win9x");

                DbConnectionPoolIdentity?currentIdentity = DbConnectionPoolIdentity.NoIdentity;
                if (_poolGroupOptions.PoolByIdentity)
                {
                    // if we're pooling by identity (because integrated security is
                    // being used for these connections) then we need to go out and
                    // search for the connectionPool that matches the current identity.

                    currentIdentity = DbConnectionPoolIdentity.GetCurrent();

                    // If the current token is restricted in some way, then we must
                    // not attempt to pool these connections.
                    if (currentIdentity.IsRestricted)
                    {
                        currentIdentity = null;
                    }
                }

                if (null != currentIdentity)
                {
                    if (!_poolCollection.TryGetValue(currentIdentity, out pool))
                    { // find the pool
                        lock (this)
                        {
                            // Did someone already add it to the list?
                            if (!_poolCollection.TryGetValue(currentIdentity, out pool))
                            {
                                DbConnectionPool newPool = new DbConnectionPool(connectionFactory, this, currentIdentity);

                                if (MarkPoolGroupAsActive())
                                {
                                    // If we get here, we know for certain that we there isn't
                                    // a pool that matches the current identity, so we have to
                                    // add the optimistically created one
                                    newPool.Startup(); // must start pool before usage
                                    bool addResult = _poolCollection.TryAdd(currentIdentity, newPool);
                                    Debug.Assert(addResult, "No other pool with current identity should exist at this point");
                                    connectionFactory.PerformanceCounters.NumberOfActiveConnectionPools.Increment();
                                    pool = newPool;
                                }
                                else
                                {
                                    // else pool entry has been disabled so don't create new pools
                                    Debug.Assert(PoolGroupStateDisabled == _state, "state should be disabled");

                                    // don't need to call connectionFactory.QueuePoolForRelease(newPool) because
                                    // pool callbacks were delayed and no risk of connections being created
                                    newPool.Shutdown();
                                }
                            }
                            else
                            {
                                // else found an existing pool to use instead
                                Debug.Assert(PoolGroupStateActive == _state, "state should be active since a pool exists and lock holds");
                            }
                        }
                    }
                    // the found pool could be in any state
                }
            }

            if (null == pool)
            {
                lock (this)
                {
                    // keep the pool entry state active when not pooling
                    MarkPoolGroupAsActive();
                }
            }
            return(pool);
        }
Example #10
0
 internal virtual bool TryReplaceConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource <DbConnectionInternal> retry, DbConnectionOptions userOptions)
 {
     throw ADP.MethodNotImplemented();
 }
 internal override bool TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource <DbConnectionInternal>?retry, DbConnectionOptions?userOptions)
 {
     return(base.TryOpenConnectionInternal(outerConnection, connectionFactory, retry, userOptions));
 }
Example #12
0
 internal override void CloseConnection(DbConnection owningObject, DbConnectionFactory connectionFactory)
 {
 }
Example #13
0
 /// <devdoc>The default implementation is for the open connection objects, and
 /// it simply throws.  Our private closed-state connection objects
 /// override this and do the correct thing.</devdoc>
 // User code should either override DbConnectionInternal.Activate when it comes out of the pool
 // or override DbConnectionFactory.CreateConnection when the connection is created for non-pooled connections
 internal virtual bool TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource <DbConnectionInternal>?retry, DbConnectionOptions?userOptions)
 {
     throw ADP.ConnectionAlreadyOpen(State);
 }
Example #14
0
        internal bool Prune()
        {
            // must only call from DbConnectionFactory.PruneConnectionPoolGroups on background timer thread
            // must lock(DbConnectionFactory._connectionPoolGroups.SyncRoot) before calling ReadyToRemove
            //     to avoid conflict with DbConnectionFactory.CreateConnectionPoolGroup replacing pool entry
            lock (this)
            {
                if (_poolCollection.Count > 0)
                {
                    var newPoolCollection = new ConcurrentDictionary <DbConnectionPoolIdentity, DbConnectionPool>();

                    foreach (var entry in _poolCollection)
                    {
                        DbConnectionPool pool = entry.Value;
                        if (pool != null)
                        {
                            //  Pruning a pool while a connection is currently attempting to connect
                            //  will cause the pool to be prematurely abandoned. The only known effect so
                            //  far is that the errorWait throttling will be reset when this occurs.
                            //  We should be able to avoid this situation by not pruning the pool if
                            //  it's _waitCount is non-zero (i.e. no connections *in* the pool, but also
                            //  no connections attempting to be created for the pool).

                            // Actually prune the pool if there are no connections in the pool and no errors occurred.
                            // Empty pool during pruning indicates zero or low activity, but
                            //  an error state indicates the pool needs to stay around to
                            //  throttle new connection attempts.
                            if ((!pool.ErrorOccurred) && (0 == pool.Count))
                            {
                                // Order is important here.  First we remove the pool
                                // from the collection of pools so no one will try
                                // to use it while we're processing and finally we put the
                                // pool into a list of pools to be released when they
                                // are completely empty.
                                DbConnectionFactory connectionFactory = pool.ConnectionFactory;

                                connectionFactory.PerformanceCounters.NumberOfActiveConnectionPools.Decrement();
                                connectionFactory.QueuePoolForRelease(pool, false);
                            }
                            else
                            {
                                newPoolCollection.TryAdd(entry.Key, entry.Value);
                            }
                        }
                    }
                    _poolCollection = newPoolCollection;
                }

                // must be pruning thread to change state and no connections
                // otherwise pruning thread risks making entry disabled soon after user calls ClearPool
                if (0 == _poolCollection.Count)
                {
                    if (PoolGroupStateActive == _state)
                    {
                        _state = PoolGroupStateIdle;
                    }
                    else if (PoolGroupStateIdle == _state)
                    {
                        _state = PoolGroupStateDisabled;
                    }
                }
                return(PoolGroupStateDisabled == _state);
            }
        }
        protected bool TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource<DbConnectionInternal> retry, DbConnectionOptions userOptions) {
            // ?->Connecting: prevent set_ConnectionString during Open
            if (connectionFactory.SetInnerConnectionFrom(outerConnection, DbConnectionClosedConnecting.SingletonInstance, this)) {
                DbConnectionInternal openConnection = null;
                try {
                    connectionFactory.PermissionDemand(outerConnection);
                    if (!connectionFactory.TryGetConnection(outerConnection, retry, userOptions, this, out openConnection)) {
                        return false;
                    }
                }
                catch {
                    // This should occure for all exceptions, even ADP.UnCatchableExceptions.
                    connectionFactory.SetInnerConnectionTo(outerConnection, this);
                    throw;
                }
                if (null == openConnection) {
                    connectionFactory.SetInnerConnectionTo(outerConnection, this);
                    throw ADP.InternalConnectionError(ADP.ConnectionError.GetConnectionReturnsNull);
                }
                connectionFactory.SetInnerConnectionEvent(outerConnection, openConnection);
            }

            return true;
        }
 internal override bool TryReplaceConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource<DbConnectionInternal> retry, DbConnectionOptions userOptions) {
     return base.TryOpenConnectionInternal(outerConnection, connectionFactory, retry, userOptions);
 }
Example #17
0
 internal override void CloseConnection(DbConnection owningObject, DbConnectionFactory connectionFactory)
 {
     // not much to do here...
 }
Example #18
0
        internal override bool TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource<DbConnectionInternal> retry, DbConnectionOptions userOptions) {

            if (retry == null || !retry.Task.IsCompleted) {
                // retry is null if this is a synchronous call

                // if someone calls Open or OpenAsync while in this state, 
                // then the retry task will not be completed

                throw ADP.ConnectionAlreadyOpen(State);
            }

            // we are completing an asynchronous open
            Debug.Assert(retry.Task.Status == TaskStatus.RanToCompletion, "retry task must be completed successfully");
            DbConnectionInternal openConnection = retry.Task.Result;
            if (null == openConnection) {
                connectionFactory.SetInnerConnectionTo(outerConnection, this);
                throw ADP.InternalConnectionError(ADP.ConnectionError.GetConnectionReturnsNull);
            }
            connectionFactory.SetInnerConnectionEvent(outerConnection, openConnection);

            return true;
        }
Example #19
0
 protected internal override DataTable GetSchema(DbConnectionFactory factory, DbConnectionPoolGroup poolGroup, DbConnection outerConnection, string collectionName, string[] restrictions)
 => throw ADP.ClosedConnectionError();
Example #20
0
 override protected internal DataTable GetSchema(DbConnectionFactory factory, DbConnectionPoolGroup poolGroup, DbConnection outerConnection, string collectionName, string[] restrictions) {
     throw ADP.ClosedConnectionError();
 }
Example #21
0
 internal override bool TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource <DbConnectionInternal> retry, DbConnectionOptions userOptions)
 => throw ADP.ConnectionAlreadyOpen(State);
 internal virtual void OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
 {
     throw ADP.ConnectionAlreadyOpen(this.State);
 }
Example #23
0
 internal override void CloseConnection(DbConnection owningObject, DbConnectionFactory connectionFactory)
 {
     connectionFactory.SetInnerConnectionTo(owningObject, DbConnectionClosedPreviouslyOpened.SingletonInstance);
 }
Example #24
0
		protected DbConnectionBase (DbConnectionFactory connectionFactory)
		{
			this.connectionFactory = connectionFactory;
		}
Example #25
0
 internal override bool TryReplaceConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource <DbConnectionInternal> retry, DbConnectionOptions userOptions)
 => TryOpenConnection(outerConnection, connectionFactory, retry, userOptions);
        internal virtual void CloseConnection(DbConnection owningObject, DbConnectionFactory connectionFactory) {
            // The implementation here is the implementation required for the
            // "open" internal connections, since our own private "closed"
            // singleton internal connection objects override this method to
            // prevent anything funny from happening (like disposing themselves
            // or putting them into a connection pool)
            //
            // Derived class should override DbConnectionInternal.Deactivate and DbConnectionInternal.Dispose
            // for cleaning up after DbConnection.Close
            //     protected override void Deactivate() { // override DbConnectionInternal.Close
            //         // do derived class connection deactivation for both pooled & non-pooled connections
            //     }
            //     public override void Dispose() { // override DbConnectionInternal.Close
            //         // do derived class cleanup
            //         base.Dispose();
            //     }
            //
            // overriding DbConnection.Close is also possible, but must provider for their own synchronization
            //     public override void Close() { // override DbConnection.Close
            //         base.Close();
            //         // do derived class outer connection for both pooled & non-pooled connections
            //         // user must do their own synchronization here
            //     }
            //
            //     if the DbConnectionInternal derived class needs to close the connection it should
            //     delegate to the DbConnection if one exists or directly call dispose
            //         DbConnection owningObject = (DbConnection)Owner;
            //         if (null != owningObject) {
            //             owningObject.Close(); // force the closed state on the outer object.
            //         }
            //         else {
            //             Dispose();
            //         }
            //
            ////////////////////////////////////////////////////////////////
            // DON'T MESS WITH THIS CODE UNLESS YOU KNOW WHAT YOU'RE DOING!
            ////////////////////////////////////////////////////////////////
            Debug.Assert(null != owningObject, "null owningObject");
            Debug.Assert(null != connectionFactory, "null connectionFactory");

            Bid.PoolerTrace("<prov.DbConnectionInternal.CloseConnection|RES|CPOOL> %d# Closing.\n", ObjectID);

            // if an exception occurs after the state change but before the try block
            // the connection will be stuck in OpenBusy state.  The commented out try-catch
            // block doesn't really help because a ThreadAbort during the finally block
            // would just refert the connection to a bad state.
            // Open->Closed: guarantee internal connection is returned to correct pool
            if (connectionFactory.SetInnerConnectionFrom(owningObject, DbConnectionOpenBusy.SingletonInstance, this)) {
                
                // Lock to prevent race condition with cancellation
                lock (this) {

                    object lockToken = ObtainAdditionalLocksForClose();
                    try {
                        PrepareForCloseConnection();

                        DbConnectionPool connectionPool = Pool;

                        // Detach from enlisted transactions that are no longer active on close
                        DetachCurrentTransactionIfEnded();

                        // The singleton closed classes won't have owners and
                        // connection pools, and we won't want to put them back
                        // into the pool.
                        if (null != connectionPool) {
                            connectionPool.PutObject(this, owningObject);   // PutObject calls Deactivate for us...
                            // NOTE: Before we leave the PutObject call, another
                            // thread may have already popped the connection from
                            // the pool, so don't expect to be able to verify it.
                        }
                        else {
                            Deactivate();   // ensure we de-activate non-pooled connections, or the data readers and transactions may not get cleaned up...

                            PerformanceCounters.HardDisconnectsPerSecond.Increment();
                        
                            // To prevent an endless recursion, we need to clear
                            // the owning object before we call dispose so that
                            // we can't get here a second time... Ordinarily, I
                            // would call setting the owner to null a hack, but
                            // this is safe since we're about to dispose the
                            // object and it won't have an owner after that for
                            // certain.
                            _owningObject.Target = null;

                            if (IsTransactionRoot) {
                                SetInStasis();                           
                            }
                            else {
                                PerformanceCounters.NumberOfNonPooledConnections.Decrement();
                                if (this.GetType() != typeof(System.Data.SqlClient.SqlInternalConnectionSmi))
                                {
                                    Dispose();
                                }
                            }
                        }
                    }
                    finally {
                        ReleaseAdditionalLocksForClose(lockToken);
                        // if a ThreadAbort puts us here then its possible the outer connection will not reference
                        // this and this will be orphaned, not reclaimed by object pool until outer connection goes out of scope.
                        connectionFactory.SetInnerConnectionEvent(owningObject, DbConnectionClosedPreviouslyOpened.SingletonInstance);
                    }
                }
            }
        }
Example #27
0
        internal virtual void CloseConnection(DbConnection owningObject, DbConnectionFactory connectionFactory)
        {
            // The implementation here is the implementation required for the
            // "open" internal connections, since our own private "closed"
            // singleton internal connection objects override this method to
            // prevent anything funny from happening (like disposing themselves
            // or putting them into a connection pool)
            //
            // Derived class should override DbConnectionInternal.Deactivate and DbConnectionInternal.Dispose
            // for cleaning up after DbConnection.Close
            //     protected override void Deactivate() { // override DbConnectionInternal.Close
            //         // do derived class connection deactivation for both pooled & non-pooled connections
            //     }
            //     public override void Dispose() { // override DbConnectionInternal.Close
            //         // do derived class cleanup
            //         base.Dispose();
            //     }
            //
            // overriding DbConnection.Close is also possible, but must provider for their own synchronization
            //     public override void Close() { // override DbConnection.Close
            //         base.Close();
            //         // do derived class outer connection for both pooled & non-pooled connections
            //         // user must do their own synchronization here
            //     }
            //
            //     if the DbConnectionInternal derived class needs to close the connection it should
            //     delegate to the DbConnection if one exists or directly call dispose
            //         DbConnection owningObject = (DbConnection)Owner;
            //         if (null != owningObject) {
            //             owningObject.Close(); // force the closed state on the outer object.
            //         }
            //         else {
            //             Dispose();
            //         }
            //
            ////////////////////////////////////////////////////////////////
            // DON'T MESS WITH THIS CODE UNLESS YOU KNOW WHAT YOU'RE DOING!
            ////////////////////////////////////////////////////////////////
            Debug.Assert(null != owningObject, "null owningObject");
            Debug.Assert(null != connectionFactory, "null connectionFactory");

            // if an exception occurs after the state change but before the try block
            // the connection will be stuck in OpenBusy state.  The commented out try-catch
            // block doesn't really help because a ThreadAbort during the finally block
            // would just revert the connection to a bad state.
            // Open->Closed: guarantee internal connection is returned to correct pool
            if (connectionFactory.SetInnerConnectionFrom(owningObject, DbConnectionOpenBusy.SingletonInstance, this))
            {
                // Lock to prevent race condition with cancellation
                lock (this)
                {
                    object lockToken = ObtainAdditionalLocksForClose();
                    try
                    {
                        PrepareForCloseConnection();

                        DbConnectionPool connectionPool = Pool;

                        // Detach from enlisted transactions that are no longer active on close
                        DetachCurrentTransactionIfEnded();

                        // The singleton closed classes won't have owners and
                        // connection pools, and we won't want to put them back
                        // into the pool.
                        if (null != connectionPool)
                        {
                            connectionPool.PutObject(this, owningObject);   // PutObject calls Deactivate for us...
                                                                            // NOTE: Before we leave the PutObject call, another
                                                                            // thread may have already popped the connection from
                                                                            // the pool, so don't expect to be able to verify it.
                        }
                        else
                        {
                            Deactivate();   // ensure we de-activate non-pooled connections, or the data readers and transactions may not get cleaned up...

                            PerformanceCounters.HardDisconnectsPerSecond.Increment();

                            // To prevent an endless recursion, we need to clear
                            // the owning object before we call dispose so that
                            // we can't get here a second time... Ordinarily, I
                            // would call setting the owner to null a hack, but
                            // this is safe since we're about to dispose the
                            // object and it won't have an owner after that for
                            // certain.
                            _owningObject.Target = null;

                            if (IsTransactionRoot)
                            {
                                SetInStasis();
                            }
                            else
                            {
                                PerformanceCounters.NumberOfNonPooledConnections.Decrement();
                                Dispose();
                            }
                        }
                    }
                    finally
                    {
                        ReleaseAdditionalLocksForClose(lockToken);
                        // if a ThreadAbort puts us here then its possible the outer connection will not reference
                        // this and this will be orphaned, not reclaimed by object pool until outer connection goes out of scope.
                        connectionFactory.SetInnerConnectionEvent(owningObject, DbConnectionClosedPreviouslyOpened.SingletonInstance);
                    }
                }
            }
        }
 internal virtual void OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory) {
     if (!TryOpenConnection(outerConnection, connectionFactory, null, null)) {
         throw ADP.InternalError(ADP.InternalErrorCode.SynchronousConnectReturnedPending);
     }
 }
 internal SqlConnection (DbConnectionFactory connectionFactory) : base (connectionFactory)
 {
         Init (String.Empty);
 }
 internal virtual bool TryReplaceConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource<DbConnectionInternal> retry, DbConnectionOptions userOptions) {
     throw ADP.MethodNotImplemented("TryReplaceConnection");
 }
 internal override void CloseConnection(DbConnection owningObject, DbConnectionFactory connectionFactory)
 {
     if (!base.IsConnectionDoomed)
     {
         this.ClearPreparedCommands();
     }
     base.CloseConnection(owningObject, connectionFactory);
 }
 internal override void OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
 {
     throw ADP.ConnectionAlreadyOpen(base.State);
 }
Example #33
0
 internal override void CloseConnection(DbConnection owningObject, DbConnectionFactory connectionFactory)
 {
     connectionFactory.SetInnerConnectionTo(owningObject, DbConnectionClosedPreviouslyOpened.SingletonInstance);
 }
Example #34
0
        // only created by DbConnectionPoolGroup.GetConnectionPool
        internal DbConnectionPool(
                            DbConnectionFactory connectionFactory,
                            DbConnectionPoolGroup connectionPoolGroup,
                            DbConnectionPoolIdentity identity,
                            DbConnectionPoolProviderInfo connectionPoolProviderInfo)
        {
            Debug.Assert(null != connectionPoolGroup, "null connectionPoolGroup");

            if ((null != identity) && identity.IsRestricted)
            {
                throw ADP.InternalError(ADP.InternalErrorCode.AttemptingToPoolOnRestrictedToken);
            }

            _state = State.Initializing;

            lock (s_random)
            { // Random.Next is not thread-safe
                _cleanupWait = s_random.Next(12, 24) * 10 * 1000; // 2-4 minutes in 10 sec intervals
            }

            _connectionFactory = connectionFactory;
            _connectionPoolGroup = connectionPoolGroup;
            _connectionPoolGroupOptions = connectionPoolGroup.PoolGroupOptions;
            _connectionPoolProviderInfo = connectionPoolProviderInfo;
            _identity = identity;

            _waitHandles = new PoolWaitHandles();

            _errorWait = ERROR_WAIT_DEFAULT;
            _errorTimer = null;  // No error yet.

            _objectList = new List<DbConnectionInternal>(MaxPoolSize);

            _poolCreateRequest = new WaitCallback(PoolCreateRequest); // used by CleanupCallback
            _state = State.Running;

            //_cleanupTimer & QueuePoolCreateRequest is delayed until DbConnectionPoolGroup calls
            // StartBackgroundCallbacks after pool is actually in the collection
        }
Example #35
0
 protected DbConnectionBase(DbConnectionFactory connectionFactory)
 {
     this.connectionFactory = connectionFactory;
 }