Beispiel #1
0
        public static SqlInternalConnection GetPooledConnection(SqlConnectionString options, out bool isInTransaction)
        {
            // If Init() has not been called, call it and set up the cached members
            if (null == _manager)
            {
                Init();
            }

            ConnectionPool           pool        = null;
            SqlConnectionPoolControl poolControl = null;
            SqlInternalConnection    con         = null;
            IntPtr SID         = IntPtr.Zero;                                 // Actual SID
            IntPtr tokenStruct = IntPtr.Zero;                                 // Struct in memory containing SID
            string encryptedConnectionString = options.EncryptedActualConnectionString;

            try {
                // GetTokenInfo and EqualSID do not work on 9x.  WindowsIdentity does not work
                // either on 9x.  In fact, after checking with native there is no way to validate the
                // user on 9x, so simply don't.  It is a known issue in native, and we will handle
                // this the same way.  _txPool is not created on 9x, so if that is not null then we
                // know we are not on 9x so go ahead do security check.
                if (options.IntegratedSecurity && !_isWindows9x)
                {
                    // If using integrated security, find the pool based on the connection string.  Then,
                    // compare the SIDs of all pools to find a match.  If no match found, create a new pool.
                    // This will guarantee anyone using integrated security will always be sent to the
                    // appropriate pool.
                    DefaultPoolControl.ObtainSidInfo(out SID, out tokenStruct);
                    pool = _manager.FindPool(encryptedConnectionString, SID);

                    // If we found a pool, then we no longer need this SID - free it's token struct!
                    // However, if we did not find a pool then we will create a new one and it will be up
                    // to that pool to free the tokenStruct memory.
                    if (null != pool)
                    {
                        Marshal.FreeHGlobal(tokenStruct);
                    }
                }
                else
                {
                    pool = _manager.FindPool(encryptedConnectionString);
                }

                if (pool == null)
                {
                    // If pool is null, then we need to create a new pool - based on the connection string
                    // and userid.  SID and tokenStruct are included for integrated security connections.
                    if (options.IntegratedSecurity && !_isWindows9x)
                    {
                        poolControl = new SqlConnectionPoolControl(encryptedConnectionString, true, SID, tokenStruct, options);
                        pool        = _manager.FindOrCreatePool(poolControl, SID); // MDAC 81288
                    }
                    else
                    {
                        poolControl = new SqlConnectionPoolControl(encryptedConnectionString, false, IntPtr.Zero, IntPtr.Zero, options);
                        pool        = _manager.FindOrCreatePool(poolControl); // MDAC 81288
                    }
                }
            }
            catch {
                // If an exception is thrown and the pool was not created or found, then we need to free the memory for
                // the token struct.
                if (null == poolControl)
                {
                    Marshal.FreeHGlobal(tokenStruct);
                }

                throw;
            }

            con = pool.GetConnection(out isInTransaction);

            // If GetObject() failed, the pool timeout occurred.
            if (con == null)
            {
                throw SQL.PooledOpenTimeout();
            }

            return(con);
        }
Beispiel #2
0
        private void PoolCreateRequest(object state)
        {
            // called by pooler to ensure pool requests are currently being satisfied -
            // creation mutex has not been obtained

            // Before creating any new connections, reclaim any released connections that
            // were not closed.
            CheckForDeadConnections();

            Counter comp = _poolCounter.Clone();

            if (comp.IsInError)
            {
                return;
            }

            int nFree  = comp.FreeCount;
            int nWait  = comp.WaitCount;
            int nTotal = comp.TotalCount;

            if ((nTotal < _ctrl.MaxPool) && (((nFree == nWait) && (nTotal > 0)) || (nFree < nWait) || (nTotal < _ctrl.MinPool)))
            {
                // Check to see if pool was created using integrated security.  If so, check to make
                // sure identity of current user matches that of user that created pool.  If it doesn't match,
                // do not create any connections on the ThreadPool thread, since either Open will fail or we
                // will open a connection for this pool that does not belong in this pool.  The side effect of this
                // is that if using integrated security min pool size cannot be guaranteed.

                // Also - GetTokenInfo and EqualSID do not work on 9x.  WindowsIdentity does not work
                // either on 9x.  In fact, after checking with native there is no way to validate the
                // user on 9x, so simply don't.  It is a known issue in native, and we will handle
                // this the same way.
                if (_ctrl.IntegratedSecurity && !SQL.IsPlatformWin9x())
                {
                    IntPtr SID         = IntPtr.Zero;
                    IntPtr tokenStruct = IntPtr.Zero;
                    try {
                        DefaultPoolControl.ObtainSidInfo(out SID, out tokenStruct);
                        if (!_ctrl.EqualSid(SID))
                        {
                            return;
                        }
                    }
                    finally {
                        Marshal.FreeHGlobal(tokenStruct);
                    }
                }

                try {
                    try {
                        // obtain creation mutex
                        _creationMutex.WaitOne();

                        SqlInternalConnection newCon;

                        comp   = _poolCounter.Clone();
                        nFree  = comp.FreeCount;
                        nWait  = comp.WaitCount;
                        nTotal = comp.TotalCount;

                        // Check IsInError again after obtaining mutex
                        if (!comp.IsInError)
                        {
                            while ((nTotal < _ctrl.MaxPool) && (((nFree == nWait) && (nTotal > 0)) || (nFree < nWait) || (nTotal < _ctrl.MinPool)))
                            {
                                newCon = CreateConnection();

                                // We do not need to check error flag here, since we know if
                                // CreateConnection returned null, we are in error case.
                                if (null != newCon)
                                {
                                    PutNewConnection(newCon);

                                    comp   = _poolCounter.Clone();
                                    nFree  = comp.FreeCount;
                                    nWait  = comp.WaitCount;
                                    nTotal = comp.TotalCount;
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                    }
                    finally { // ReleaseMutex
                        // always release
                        _creationMutex.ReleaseMutex();
                    }
                }
                catch { // MDAC 80973
                    throw;
                }
            }
        }