public bool Select(SelectItem[] items, int itemsCount, int timeout) { if (items == null) { throw new FaultException(); } if (itemsCount == 0) { if (timeout == 0) { return(false); } Thread.Sleep(timeout); return(false); } bool firstPass = true; int numberOfEvents = 0; Stopwatch stopwatch = null; while (true) { int currentTimeoutMicroSeconds; if (firstPass) { currentTimeoutMicroSeconds = 0; } else if (timeout == -1) { currentTimeoutMicroSeconds = -1; } else { currentTimeoutMicroSeconds = (int)((timeout - stopwatch.ElapsedMilliseconds) * 1000); if (currentTimeoutMicroSeconds < 0) { currentTimeoutMicroSeconds = 0; } } m_checkRead.Clear(); m_checkWrite.Clear(); m_checkError.Clear(); for (int i = 0; i < itemsCount; i++) { var pollItem = items[i]; if (pollItem.Socket != null) { if (pollItem.Event != PollEvents.None && pollItem.Socket.Handle.Connected) { m_checkRead.Add(pollItem.Socket.Handle); } } else { if ((pollItem.Event & PollEvents.PollIn) == PollEvents.PollIn) { m_checkRead.Add(pollItem.FileDescriptor); } if ((pollItem.Event & PollEvents.PollOut) == PollEvents.PollOut) { m_checkWrite.Add(pollItem.FileDescriptor); } } } try { SocketUtility.Select(m_checkRead, m_checkWrite, m_checkError, currentTimeoutMicroSeconds); } catch (SocketException) { throw new FaultException(); } for (int i = 0; i < itemsCount; i++) { var selectItem = items[i]; selectItem.ResultEvent = PollEvents.None; if (selectItem.Socket != null) { PollEvents events = (PollEvents)selectItem.Socket.GetSocketOption(ZmqSocketOptions.Events); if ((selectItem.Event & PollEvents.PollIn) == PollEvents.PollIn && (events & PollEvents.PollIn) == PollEvents.PollIn) { selectItem.ResultEvent |= PollEvents.PollIn; } if ((selectItem.Event & PollEvents.PollOut) == PollEvents.PollOut && (events & PollEvents.PollOut) == PollEvents.PollOut) { selectItem.ResultEvent |= PollEvents.PollOut; } } else { if (m_checkRead.Contains(selectItem.FileDescriptor)) { selectItem.ResultEvent |= PollEvents.PollIn; } if (m_checkWrite.Contains(selectItem.FileDescriptor)) { selectItem.ResultEvent |= PollEvents.PollOut; } } if (selectItem.ResultEvent != PollEvents.None) { numberOfEvents++; } } if (timeout == 0) { break; } if (numberOfEvents > 0) { break; } if (timeout < 0) { if (firstPass) { firstPass = false; } continue; } if (firstPass) { stopwatch = Stopwatch.StartNew(); firstPass = false; continue; } if (stopwatch.ElapsedMilliseconds > timeout) { break; } } return(numberOfEvents > 0); }
private void Loop() { List <Socket> readList = new List <Socket>(); List <Socket> writeList = new List <Socket>(); List <Socket> errorList = new List <Socket>(); while (!m_stopping) { m_handles.AddRange(m_addList); m_addList.Clear(); // Execute any due timers. int timeout = ExecuteTimers(); readList.AddRange(m_checkRead.ToArray()); writeList.AddRange(m_checkWrite.ToArray()); errorList.AddRange(m_checkError.ToArray()); try { SocketUtility.Select(readList, writeList, errorList, timeout != 0 ? timeout * 1000 : -1); } catch (SocketException) { continue; } foreach (var pollSet in m_handles) { if (pollSet.Cancelled) { continue; } if (errorList.Contains(pollSet.Socket)) { try { pollSet.Handler.InEvent(); } catch (TerminatingException) { } } if (pollSet.Cancelled) { continue; } if (writeList.Contains(pollSet.Socket)) { try { pollSet.Handler.OutEvent(); } catch (TerminatingException) { } } if (pollSet.Cancelled) { continue; } if (readList.Contains(pollSet.Socket)) { try { pollSet.Handler.InEvent(); } catch (TerminatingException) { } } } errorList.Clear(); writeList.Clear(); readList.Clear(); if (m_retired) { foreach (var item in m_handles.Where(k => k.Cancelled).ToList()) { m_handles.Remove(item); } m_retired = false; } } }
/// <summary> /// This method is the polling-loop that is invoked on a background thread when Start is called. /// As long as Stop hasn't been called: execute the timers, and invoke the handler-methods on each of the saved PollSets. /// </summary> private void Loop() { List <Socket> readList = new List <Socket>(); List <Socket> writeList = new List <Socket>(); List <Socket> errorList = new List <Socket>(); while (!m_stopping) { // Transfer any sockets from the add-list. m_handles.AddRange(m_addList); m_addList.Clear(); // Execute any due timers. int timeout = ExecuteTimers(); readList.AddRange(m_checkRead.ToArray()); writeList.AddRange(m_checkWrite.ToArray()); errorList.AddRange(m_checkError.ToArray()); try { SocketUtility.Select(readList, writeList, errorList, timeout != 0 ? timeout * 1000 : -1); } catch (SocketException) { continue; } // For every PollSet in our list.. foreach (var pollSet in m_handles) { if (pollSet.Cancelled) { continue; } // Invoke its handler's InEvent if it's in our error-list. if (errorList.Contains(pollSet.Socket)) { try { pollSet.Handler.InEvent(); } catch (TerminatingException) { } } if (pollSet.Cancelled) { continue; } // Invoke its handler's OutEvent if it's in our write-list. if (writeList.Contains(pollSet.Socket)) { try { pollSet.Handler.OutEvent(); } catch (TerminatingException) { } } if (pollSet.Cancelled) { continue; } // Invoke its handler's InEvent if it's in our read-list. if (readList.Contains(pollSet.Socket)) { try { pollSet.Handler.InEvent(); } catch (TerminatingException) { } } } errorList.Clear(); writeList.Clear(); readList.Clear(); if (m_retired) { // Take any sockets that have been cancelled out of the list.. foreach (var item in m_handles.Where(k => k.Cancelled).ToList()) { m_handles.Remove(item); } m_retired = false; } } m_stopped = true; }
/// <summary> /// /// </summary> /// <param name="items"> (must not be null)</param> /// <param name="itemsCount"></param> /// <param name="timeout">a time-out period, in milliseconds</param> /// <returns></returns> public bool Select(SelectItem[] items, int itemsCount, int timeout) { if (items == null) { throw new FaultException("Selector.Select called with items equal to null."); } if (itemsCount == 0) { if (timeout == 0) { return(false); } //TODO: Do we really want to simply sleep and return, doing nothing during this interval? Thread.Sleep(timeout); return(false); } bool firstPass = true; int numberOfEvents = 0; Stopwatch stopwatch = null; while (true) { int currentTimeoutMicroSeconds; if (firstPass) { currentTimeoutMicroSeconds = 0; } else if (timeout == -1) { currentTimeoutMicroSeconds = -1; } else { currentTimeoutMicroSeconds = (int)((timeout - stopwatch.ElapsedMilliseconds) * 1000); if (currentTimeoutMicroSeconds < 0) { currentTimeoutMicroSeconds = 0; } } m_checkRead.Clear(); m_checkWrite.Clear(); m_checkError.Clear(); for (int i = 0; i < itemsCount; i++) { var pollItem = items[i]; if (pollItem.Socket != null) { if (pollItem.Event != PollEvents.None && pollItem.Socket.Handle.Connected) { m_checkRead.Add(pollItem.Socket.Handle); } } else { if ((pollItem.Event & PollEvents.PollIn) == PollEvents.PollIn) { m_checkRead.Add(pollItem.FileDescriptor); } if ((pollItem.Event & PollEvents.PollOut) == PollEvents.PollOut) { m_checkWrite.Add(pollItem.FileDescriptor); } } } try { SocketUtility.Select(m_checkRead, m_checkWrite, m_checkError, currentTimeoutMicroSeconds); } catch (SocketException x) { #if DEBUG string textOfListRead = StringLib.AsString(m_checkRead); string textOfListWrite = StringLib.AsString(m_checkWrite); string textOfListError = StringLib.AsString(m_checkError); string xMsg = String.Format("In Selector.Select, Socket.Select({0}, {1}, {2}, {3}) threw a SocketException: {4}", textOfListRead, textOfListWrite, textOfListError, currentTimeoutMicroSeconds, x.Message); Debug.WriteLine(xMsg); throw new FaultException(innerException: x, message: xMsg); #else throw new FaultException(innerException: x, message: "Within SocketUtility.Select"); #endif } for (int i = 0; i < itemsCount; i++) { var selectItem = items[i]; selectItem.ResultEvent = PollEvents.None; if (selectItem.Socket != null) { PollEvents events = (PollEvents)selectItem.Socket.GetSocketOption(ZmqSocketOptions.Events); if ((selectItem.Event & PollEvents.PollIn) == PollEvents.PollIn && (events & PollEvents.PollIn) == PollEvents.PollIn) { selectItem.ResultEvent |= PollEvents.PollIn; } if ((selectItem.Event & PollEvents.PollOut) == PollEvents.PollOut && (events & PollEvents.PollOut) == PollEvents.PollOut) { selectItem.ResultEvent |= PollEvents.PollOut; } } else { if (m_checkRead.Contains(selectItem.FileDescriptor)) { selectItem.ResultEvent |= PollEvents.PollIn; } if (m_checkWrite.Contains(selectItem.FileDescriptor)) { selectItem.ResultEvent |= PollEvents.PollOut; } } if (selectItem.ResultEvent != PollEvents.None) { numberOfEvents++; } } if (timeout == 0) { break; } if (numberOfEvents > 0) { break; } if (timeout < 0) { if (firstPass) { firstPass = false; } continue; } if (firstPass) { stopwatch = Stopwatch.StartNew(); firstPass = false; continue; } if (stopwatch.ElapsedMilliseconds > timeout) { break; } } return(numberOfEvents > 0); }