// 10 seconds. /// <summary> /// Waits on the channel with the given timeout using one of the /// cached selectors. /// </summary> /// <remarks> /// Waits on the channel with the given timeout using one of the /// cached selectors. It also removes any cached selectors that are /// idle for a few seconds. /// </remarks> /// <param name="channel"/> /// <param name="ops"/> /// <param name="timeout"/> /// <returns/> /// <exception cref="System.IO.IOException"/> internal virtual int Select(SelectableChannel channel, int ops, long timeout) { SocketIOWithTimeout.SelectorPool.SelectorInfo info = Get(channel); SelectionKey key = null; int ret = 0; try { while (true) { long start = (timeout == 0) ? 0 : Time.Now(); key = channel.Register(info.selector, ops); ret = info.selector.Select(timeout); if (ret != 0) { return(ret); } if (Thread.CurrentThread().IsInterrupted()) { throw new ThreadInterruptedException("Interrupted while waiting for " + "IO on channel " + channel + ". " + timeout + " millis timeout left."); } /* Sometimes select() returns 0 much before timeout for * unknown reasons. So select again if required. */ if (timeout > 0) { timeout -= Time.Now() - start; if (timeout <= 0) { return(0); } } } } finally { if (key != null) { key.Cancel(); } //clear the canceled key. try { info.selector.SelectNow(); } catch (IOException e) { Log.Info("Unexpected Exception while clearing selector : ", e); // don't put the selector back. info.Close(); return(ret); } Release(info); } }
/// <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(); } } }