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; } }
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); } }
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); }
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; }