Exemple #1
0
        /// <summary>
        /// If visual is on channel, its reference count is increased.
        /// Otherwise, a new resource is created on that channel.
        /// </summary>
        internal bool ReleaseOnChannel(DUCE.Channel channel)
        {
            int  index        = Find(channel);
            bool proxyRemoved = false;
            int  count        = Count;

            if (index == PROXY_STORED_INLINE)
            {
                if (channel.ReleaseOnChannel(_head.Handle))
                {
                    //
                    // Need to move the last of the non-empty tail to head
                    // or clear the head. Erase the head if that was the last
                    // proxy.
                    //

                    if (count == 1)
                    {
                        _head = new Proxy();
                    }
                    else
                    {
                        _head = _tail[count - 2];
                    }

                    proxyRemoved = true;
                }
            }
            else if (index >= 0)
            {
                if (channel.ReleaseOnChannel(_tail[index].Handle))
                {
                    //
                    // Need to move the last of the non-empty tail to the
                    // removed index. Avoid in-place copying.
                    //

                    if (index != count - 2)
                    {
                        _tail[index] = _tail[count - 2];
                    }

                    proxyRemoved = true;
                }
            }
            else
            {
                Debug.Assert(index != PROXY_NOT_FOUND);
                return(false);
            }

            if (proxyRemoved)
            {
                if (_tail != null)
                {
                    //
                    // Keep the tail short. We allow for one extra free element
                    // in tail to avoid constant allocations / reallocations.
                    //

                    if (count == 2)
                    {
                        //                        ------------------
                        // Before removal: [head] [tail c-1] [empty]
                        // Here and now:   [head] [ deleted] [empty]
                        // After removal:  [head]
                        //

                        _tail = null;
                    }
                    else if (count == _tail.Length)
                    {
                        //                        ---------------------------------------------------
                        // Before removal: [head] [tail 0] [tail 1] ... [tail c-3] [tail c-2] [empty]
                        // Here and now:   [head] [tail 0] [tail 1] ... [tail c-3] [ deleted] [empty]
                        // After removal:  [head] [tail 0] [tail 1] ... [tail c-3]
                        //

                        ResizeTail(-2);
                    }
                    else
                    {
                        //                        ------------------------------------------------------
                        // Before removal: [head] [tail 0] [tail 1] ... [tail c-4] [tail c-3] [tail c-2]
                        // Here and now:   [head] [tail 0] [tail 1] ... [tail c-4] [tail c-3] [ deleted]
                        // After removal:  [head] [tail 0] [tail 1] ... [tail c-4] [tail c-3] [   empty]
                        //

                        _tail[count - 2] = new Proxy();
                    }
                }
            }

            return(proxyRemoved);
        }