Пример #1
0
        public ConnectionPool FindOrCreatePool(DefaultPoolControl ctrl)
        {
            Debug.Assert(ctrl != null, "Unexpected DefaultPoolControl null!");
            // Should not be calling this FindOrCreatePool if using integrated security.
            Debug.Assert(!ctrl.IntegratedSecurity, "Using integrated security and wrong FindOrCreatePool called");

            String         poolKey = ctrl.Key;
            ConnectionPool pool    = FindPool(poolKey);

            if (pool == null)
            {
                try {
                    lock (_map.SyncRoot) {
                        // Did somebody else created it while we were waiting?
                        pool = FindPool(poolKey);

                        if (pool == null)
                        {
                            // Create a new pool, shove it into the map:
                            pool          = new ConnectionPool(ctrl);
                            _map[poolKey] = pool;
                        }
                    }
                }
                catch { // MDAC 80973
                    throw;
                }
            }

            return(pool);
        }
Пример #2
0
        public ConnectionPool(DefaultPoolControl ctrl)
        {
            _state       = State.Initializing;
            _ctrl        = ctrl;
            _poolCounter = new Counter();
            _stackOld    = new InterlockedStack();
            _stackNew    = new InterlockedStack();
            _waitHandles = new ObjectPoolWaitHandle[3];
            _waitHandles[SEMAPHORE_HANDLE] = CreateWaitHandle(SafeNativeMethods.CreateSemaphore(ADP.PtrZero, 0, MAX_Q_SIZE, ADP.PtrZero), false);
            _waitHandles[ERROR_HANDLE]     = CreateWaitHandle(SafeNativeMethods.CreateEvent(ADP.PtrZero, 1, 0, ADP.PtrZero), false);
            _creationMutex = new Mutex();
            _waitHandles[CREATION_HANDLE] = CreateWaitHandle(_creationMutex.Handle, true);
            _errorWait   = ERROR_WAIT_DEFAULT;
            _cleanupWait = 0;    // Set in CreateCleanupTimer
            _errorTimer  = null; // No error yet.
            _connections = new ArrayList(_ctrl.MaxPool);

            if (ctrl.TransactionAffinity)
            {
                if (SQL.IsPlatformNT5())
                {
                    _txPool = CreateResourcePool();
                }
            }

            _cleanupTimer = CreateCleanupTimer();
            _state        = State.Running;

            // PerfCounters - this counter will never be decremented!
            SQL.IncrementPoolCount();

            // Make sure we're at quota by posting a callback to the threadpool.
            ThreadPool.QueueUserWorkItem(new WaitCallback(PoolCreateRequest));
        }
Пример #3
0
        public ConnectionPool FindOrCreatePool(DefaultPoolControl ctrl, IntPtr SID)
        {
            Debug.Assert(ctrl != null, "Unexpected DefaultPoolControl null!");
            Debug.Assert(ctrl.IntegratedSecurity, "DefaultPoolControl unexpectedly not using integrated security");
            Debug.Assert(!SQL.IsPlatformWin9x(), "FindOrCreatePool that expects not 9x called on 9x!");
            Debug.Assert(SID != IntPtr.Zero, "Unexpected SID == IntPtr.Zero!");

            String         poolKey = ctrl.Key;
            ConnectionPool pool    = FindPool(poolKey, SID);

            if (pool == null)
            {
                try {
                    lock (_mapSSPI.SyncRoot) {
                        // Did somebody else created it while we were waiting?
                        pool = FindPool(poolKey, SID);

                        if (pool == null)
                        {
                            // Create a new pool, shove it into the map:
                            pool = new ConnectionPool(ctrl);
                            ArrayList items = (ArrayList)_mapSSPI[poolKey];
                            if (null == items)
                            {
                                items             = new ArrayList();
                                _mapSSPI[poolKey] = items;
                            }

                            items.Add(pool);
                        }
                    }
                }
                catch { // MDAC 80973
                    throw;
                }
            }

            return(pool);
        }
Пример #4
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);
        }
Пример #5
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;
                }
            }
        }