示例#1
0
        public RpcTcpBufferPool(int capacity, Func <T> allocator)
        {
            //
            // 所有的capacity都是2的幂
            IICAssert.IsTrue(capacity < 1024 * 1024);

            _capacity     = NumberUtils.NextPower2(capacity);
            _nodes        = new CachedNode[_capacity];
            _capacityMask = _capacity - 1;
            _count        = _capacity;

            //
            // 填充满所有对象
            for (int i = 0; i < _capacity; i++)
            {
                var node = new CachedNode()
                {
                    Value   = allocator(),
                    Fetched = 0,
                    Index   = i,
                };

                node.Value.CachedIndex = i;
                _nodes[i] = node;
            }
        }
示例#2
0
        public void Release(T value)
        {
            CachedNode node = _nodes[value.CachedIndex];

            //
            // 实际Release掉了, 就增加可用数量
            //原先FetchPrepare在CompareExchange里面,会导致node马上被另一个线程fetch使用后,却被FetchPrepare()清了所有内容
            //造成callback不能回调,依附sokcket sendpending一直增加,这个asynarg 不能会导池内
            node.Value.FetchPrepare();
            if (Interlocked.CompareExchange(ref node.Fetched, 0, 1) == 1)
            {
                Interlocked.Increment(ref _count);
            }
        }
示例#3
0
        public T Fetch()
        {
            //
            // 先减小对象数,避免容器空
            int count = Interlocked.Decrement(ref _count);

            if (count < 0)
            {
                Interlocked.Increment(ref _count);
                return(default(T));
            }

            //
            // 在head后寻找第一个可用,然后获取值
            int        index = -1;
            CachedNode node  = null;

            do
            {
                index = Interlocked.Increment(ref _head) & _capacityMask;
                node  = _nodes[index];
            } while (Interlocked.CompareExchange(ref node.Fetched, 1, 0) != 0);
            return(node.Value);
        }
示例#4
0
        private CachedNode AddCachedNode(Node node)
        {
            CachedNode cachedNode;
            if (_cacheNodes.TryGetValue(node.Id, out cachedNode))
                return cachedNode; //exists

            if (_cacheNodes.Count > MaxCacheNodes)
                _cacheNodes.Remove(_cacheNodes.First().Key);

            cachedNode = new CachedNode(node);
            _cacheNodes.Add(node.Id, cachedNode);
            return cachedNode;
        }