ReleaseSemaphore() private method

private ReleaseSemaphore ( ) : bool
return bool
        /// <devdoc>
        ///    <para>Places a new/reusable stream in the new stack of the pool</para>
        /// </devdoc>
        private void PutNew(PooledStream pooledStream)
        {
            GlobalLog.Enter("ConnectionPool#" + ValidationHelper.HashString(this) + "::PutNew", "#" + ValidationHelper.HashString(pooledStream));

            GlobalLog.Assert(null != pooledStream, "Why are we adding a null object to the pool?");
            GlobalLog.Assert(pooledStream.CanBePooled, "Non-poolable object in pool.");

            m_StackNew.Push(pooledStream);
            Semaphore.ReleaseSemaphore();
            GlobalLog.Leave("ConnectionPool#" + ValidationHelper.HashString(this) + "::PutNew");
        }
        /// <devdoc>
        ///    <para>Places a new/reusable stream in the new stack of the pool</para>
        /// </devdoc>
        private void PutNew(PooledStream pooledStream)
        {
            GlobalLog.Enter("ConnectionPool#" + ValidationHelper.HashString(this) + "::PutNew", "#" + ValidationHelper.HashString(pooledStream));

            GlobalLog.Assert(null != pooledStream, "Why are we adding a null object to the pool?");
            GlobalLog.Assert(pooledStream.CanBePooled, "Non-poolable object in pool.");

            m_StackNew.Push(pooledStream);
            // ensure that the semaphore's count is incremented to signal an available connection is in
            // the pool
            Semaphore.ReleaseSemaphore();
            GlobalLog.Leave("ConnectionPool#" + ValidationHelper.HashString(this) + "::PutNew");
        }
        /// <summary>
        ///    <para>This is called by a timer, to check for needed cleanup of idle pooled streams</para>
        /// </summary>
        private void CleanupCallback()
        {
            // Called when the cleanup-timer ticks over.
            //
            // This is the automatic prunning method.  Every period, we will perform a two-step
            // process.  First, for the objects above MinPool, we will obtain the semaphore for
            // the object and then destroy it if it was on the old stack.  We will continue this
            // until we either reach MinPool size, or we are unable to obtain a free object, or
            // until we have exhausted all the objects on the old stack.  After that, push all
            // objects on the new stack to the old stack.  So, every period the objects on the
            // old stack are destroyed and the objects on the new stack are pushed to the old
            // stack.  All objects that are currently out and in use are not on either stack.
            // With this logic, a object is prunned if unused for at least one period but not
            // more than two periods.

            // Destroy free objects above MinPool size from old stack.
            while (Count > MinPoolSize)  // While above MinPoolSize...

            {
                if (Semaphore.WaitOne(0, false))    // != WaitTimeout
                // We obtained a objects from the semaphore.
                {
                    PooledStream pooledStream = (PooledStream)m_StackOld.Pop();

                    if (null != pooledStream)
                    {
                        // If we obtained one from the old stack, destroy it.
                        Destroy(pooledStream);
                    }
                    else
                    {
                        // Else we exhausted the old stack, so break.
                        Semaphore.ReleaseSemaphore();
                        break;
                    }
                }
                else
                {
                    break;
                }
            }

            // Push to the old-stack.  For each free object, move object from new stack
            // to old stack.
            if (Semaphore.WaitOne(0, false))  //  != WaitTimeout
            {
                for (;;)
                {
                    PooledStream pooledStream = (PooledStream)m_StackNew.Pop();

                    if (null == pooledStream)
                    {
                        break;
                    }

                    GlobalLog.Assert(!pooledStream.IsEmancipated, "Pooled object not in pool.");
                    GlobalLog.Assert(pooledStream.CanBePooled, "Pooled object is not poolable.");

                    m_StackOld.Push(pooledStream);
                }
                Semaphore.ReleaseSemaphore();
            }
        }
        /// <summary>
        ///    <para>This is called by a timer, to check for needed cleanup of idle pooled streams</para>
        /// </summary>
        private void CleanupCallback()
        {
            // Called when the cleanup-timer ticks over.
            //
            // This is the automatic prunning method.  Every period, we will perform a two-step
            // process.  First, for the objects above MinPool, we will obtain the semaphore for
            // the object and then destroy it if it was on the old stack.  We will continue this
            // until we either reach MinPool size, or we are unable to obtain a free object, or
            // until we have exhausted all the objects on the old stack.  After that, push all
            // objects on the new stack to the old stack.  So, every period the objects on the
            // old stack are destroyed and the objects on the new stack are pushed to the old
            // stack.  All objects that are currently out and in use are not on either stack.
            // With this logic, a object is prunned if unused for at least one period but not
            // more than two periods.

            // Destroy free objects above MinPool size from old stack.
            while (Count > MinPoolSize)  // While above MinPoolSize...

            // acquiring the Semaphore gives us a license to remove one and only
            // one connection from the pool
            {
                if (Semaphore.WaitOne(0, false))    // != WaitTimeout
                // We obtained a objects from the semaphore.
                {
                    PooledStream pooledStream = (PooledStream)m_StackOld.Pop();

                    if (null != pooledStream)
                    {
                        // If we obtained one from the old stack, destroy it.
                        Destroy(pooledStream);
                    }
                    else
                    {
                        // Else we exhausted the old stack, so break
                        // and release the Semaphore to indicate that
                        // no connection was actually removed so whatever
                        // we had locked is still available.
                        Semaphore.ReleaseSemaphore();
                        break;
                    }
                }
                else
                {
                    break;
                }
            }

            // Push to the old-stack.  For each free object, move object from new stack
            // to old stack.  The Semaphore guarantees that we are allowed to handle
            // one connection at a time so moving a connection between stacks is safe since
            // one connection is reserved for the duration of this loop and we only touch
            // one connection at a time on the new stack
            if (Semaphore.WaitOne(0, false))  //  != WaitTimeout
            {
                for (;;)
                {
                    PooledStream pooledStream = (PooledStream)m_StackNew.Pop();

                    if (null == pooledStream)
                    {
                        break;
                    }

                    GlobalLog.Assert(!pooledStream.IsEmancipated, "Pooled object not in pool.");
                    GlobalLog.Assert(pooledStream.CanBePooled, "Pooled object is not poolable.");

                    m_StackOld.Push(pooledStream);
                }
                // no connections were actually destroyed so signal that a connection is now
                // available since we are no longer reserving a connection by holding the
                // Semaphore
                Semaphore.ReleaseSemaphore();
            }
        }