private static string TimeoutExceptionString(SelectableChannel channel, long timeout , int ops) { string waitingFor; switch (ops) { case SelectionKey.OpRead: { waitingFor = "read"; break; } case SelectionKey.OpWrite: { waitingFor = "write"; break; } case SelectionKey.OpConnect: { waitingFor = "connect"; break; } default: { waitingFor = string.Empty + ops; break; } } return(timeout + " millis timeout while " + "waiting for channel to be ready for " + waitingFor + ". ch : " + channel); }
// 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); } }
/// <exception cref="System.IO.IOException"/> internal SocketIOWithTimeout(SelectableChannel channel, long timeout) { // This is intentionally package private. /* A timeout value of 0 implies wait for ever. * We should have a value of timeout that implies zero wait.. i.e. * read or write returns immediately. * * This will set channel to non-blocking. */ CheckChannelValidity(channel); this.channel = channel; this.timeout = timeout; // Set non-blocking channel.ConfigureBlocking(false); }
/// <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); } }
protected AbstractNioChannel(Channel parent, SelectableChannel ch) : base(parent) { this.ch = ch; }
protected AbstractChannel(Channel _parent, SelectableChannel ch = null) : this() { this._parent = _parent; this.ch = ch; }