/// <summary>Takes one selector from end of LRU list of free selectors.</summary> /// <remarks> /// Takes one selector from end of LRU list of free selectors. /// If there are no selectors awailable, it creates a new selector. /// Also invokes trimIdleSelectors(). /// </remarks> /// <param name="channel"/> /// <returns></returns> /// <exception cref="System.IO.IOException"/> private SocketIOWithTimeout.SelectorPool.SelectorInfo Get(SelectableChannel channel ) { lock (this) { SocketIOWithTimeout.SelectorPool.SelectorInfo selInfo = null; SelectorProvider provider = channel.Provider(); // pick the list : rarely there is more than one provider in use. SocketIOWithTimeout.SelectorPool.ProviderInfo pList = providerList; while (pList != null && pList.provider != provider) { pList = pList.next; } if (pList == null) { //LOG.info("Creating new ProviderInfo : " + provider.toString()); pList = new SocketIOWithTimeout.SelectorPool.ProviderInfo(); pList.provider = provider; pList.queue = new List <SocketIOWithTimeout.SelectorPool.SelectorInfo>(); pList.next = providerList; providerList = pList; } List <SocketIOWithTimeout.SelectorPool.SelectorInfo> queue = pList.queue; if (queue.IsEmpty()) { Selector selector = provider.OpenSelector(); selInfo = new SocketIOWithTimeout.SelectorPool.SelectorInfo(); selInfo.selector = selector; selInfo.queue = queue; } else { selInfo = queue.RemoveLast(); } TrimIdleSelectors(Time.Now()); return(selInfo); } }
/// <summary>Closes selectors that are idle for IDLE_TIMEOUT (10 sec).</summary> /// <remarks> /// Closes selectors that are idle for IDLE_TIMEOUT (10 sec). It does not /// traverse the whole list, just over the one that have crossed /// the timeout. /// </remarks> private void TrimIdleSelectors(long now) { long cutoff = now - IdleTimeout; for (SocketIOWithTimeout.SelectorPool.ProviderInfo pList = providerList; pList != null; pList = pList.next) { if (pList.queue.IsEmpty()) { continue; } for (IEnumerator <SocketIOWithTimeout.SelectorPool.SelectorInfo> it = pList.queue. GetEnumerator(); it.HasNext();) { SocketIOWithTimeout.SelectorPool.SelectorInfo info = it.Next(); if (info.lastActivityTime > cutoff) { break; } it.Remove(); info.Close(); } } }