Ejemplo n.º 1
0
        public void Enqueue(ref T data, OnWorkItemComplete <T> onComplete = null, WorkQueueNotifyMode notifyChanged = WorkQueueNotifyMode.Always)
        {
#if DEBUG
            if (IsMainThreadWorkItem && !IsMainThreadQueue)
            {
                throw new InvalidOperationException("This work item must be queued on the main thread");
            }
#endif

            var wi       = new InternalWorkItem <T>(this, ref data, onComplete);
            var newCount = AddInternal(ref wi);
            NotifyChanged(notifyChanged, newCount, wakeAll: false);
        }
Ejemplo n.º 2
0
        private void NotifyChanged(WorkQueueNotifyMode mode, int newCount, bool wakeAll = true)
        {
            switch (mode)
            {
            case WorkQueueNotifyMode.Never:
                return;

            default:
            case WorkQueueNotifyMode.Always:
                Owner.NotifyQueuesChanged(wakeAll);
                return;

            case WorkQueueNotifyMode.Stochastically:
                if ((newCount % Configuration.StochasticNotifyInterval) == 0)
                {
                    // We're already only waking the queues intermittently so we always want wakeAll = true here
                    Owner.NotifyQueuesChanged(true);
                }
                return;
            }
        }
Ejemplo n.º 3
0
        public void Release(ref UnorderedList <T> _list, WorkQueueNotifyMode notifyMode)
        {
            var list = _list;

            _list = null;

            if (list == null)
            {
                return;
            }

            if (list.Capacity > SmallPoolMaxItemSize)
            {
                if (list.Capacity <= LargePoolMaxItemSize)
                {
                    lock (_LargePool) {
                        if (_LargePool.Count >= LargePoolCapacity)
                        {
                            return;
                        }
                    }

                    ClearAndReturn(list, _LargePool, LargePoolCapacity, notifyMode);
                }

                return;
            }

            lock (_Pool) {
                if (_Pool.Count >= SmallPoolCapacity)
                {
                    return;
                }
            }

            ClearAndReturn(list, _Pool, SmallPoolCapacity, notifyMode);
        }
Ejemplo n.º 4
0
        private void ClearAndReturn(UnorderedList <T> list, UnorderedList <UnorderedList <T> > pool, int limit, WorkQueueNotifyMode notifyMode = WorkQueueNotifyMode.Stochastically)
        {
            if (
                !FastClearEnabled &&
                (list.Count > DeferredClearSizeThreshold) &&
                (_ClearQueue != null)
                )
            {
                _ClearQueue.Enqueue(new ListClearWorkItem {
                    List = list,
                }, notifyChanged: notifyMode);
                return;
            }

            // HACK: Acquiring the lock here would be technically correct but
            //  unnecessarily slow, since we're just trying to avoid doing a clear
            //  in cases where the list will be GCd anyway
            if (pool.Count >= limit)
            {
                return;
            }

            if (FastClearEnabled)
            {
                list.UnsafeFastClear();
            }
            else
            {
                list.Clear();
            }

            lock (pool) {
                if (pool.Count >= limit)
                {
                    return;
                }

                pool.Add(list);
            }
        }