/// <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> /// <exception cref="FaultException">The internal select operation failed.</exception> /// <exception cref="ArgumentNullException"><paramref name="items"/> is <c>null</c>.</exception> /// <exception cref="TerminatingException">The socket has been stopped.</exception> public bool Select( SelectItem[] items, int itemsCount, long timeout) { if (items == null) throw new ArgumentNullException("items"); if (itemsCount == 0) { return false; } bool firstPass = true; int numberOfEvents = 0; Stopwatch stopwatch = null; while (true) { long currentTimeoutMicroSeconds; if (firstPass) { currentTimeoutMicroSeconds = 0; } else if (timeout < 0) { // Consider everything below 0 to be infinite currentTimeoutMicroSeconds = -1; } else { currentTimeoutMicroSeconds = (timeout - stopwatch.ElapsedMilliseconds) * 1000; if (currentTimeoutMicroSeconds < 0) { currentTimeoutMicroSeconds = 0; } else if (currentTimeoutMicroSeconds > int.MaxValue) { currentTimeoutMicroSeconds = int.MaxValue; } } 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.HasIn()) m_checkRead.Add(pollItem.FileDescriptor); if (pollItem.Event.HasOut()) m_checkWrite.Add(pollItem.FileDescriptor); } } try { SocketUtility.Select(m_checkRead, m_checkWrite, m_checkError, (int)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) { var events = (PollEvents)selectItem.Socket.GetSocketOption(ZmqSocketOption.Events); if (selectItem.Event.HasIn() && events.HasIn()) selectItem.ResultEvent |= PollEvents.PollIn; if (selectItem.Event.HasOut() && events.HasOut()) 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; } // Check also equality as it might frequently occur on 1000Hz clock if (stopwatch.ElapsedMilliseconds >= timeout) break; } return numberOfEvents > 0; }
private void RebuildPollset() { #if !NET35 Debug.Assert(m_isSchedulerThread.Value); #endif // Recreate the m_pollSet and m_pollact arrays. m_pollSet = new SelectItem[m_sockets.Count + m_pollinSockets.Count]; m_pollact = new NetMQSocket[m_sockets.Count]; // For each socket in m_sockets, // put a corresponding SelectItem into the m_pollSet array and a reference to the socket itself into the m_pollact array. uint index = 0; foreach (var socket in m_sockets) { m_pollSet[index] = new SelectItem(socket.SocketHandle, socket.GetPollEvents()); m_pollact[index] = socket; index++; } foreach (var socket in m_pollinSockets.Keys) { m_pollSet[index] = new SelectItem(socket, PollEvents.PollError | PollEvents.PollIn); index++; } // Mark this as NOT having any fresh events to attend to, as yet. m_isPollSetDirty = false; }
private void RebuildPollset() { m_pollSize = m_sockets.Count + m_pollinSockets.Count; // Recreate the m_pollset and m_pollact arrays. m_pollset = new SelectItem[m_pollSize]; m_pollact = new NetMQSocket[m_sockets.Count]; // For each socket in m_sockets, // put a corresponding SelectItem into the m_pollset array and a reference to the socket itself into the m_pollact array. uint itemNbr = 0; foreach (var socket in m_sockets) { m_pollset[itemNbr] = new SelectItem(socket.SocketHandle, socket.GetPollEvents()); m_pollact[itemNbr] = socket; itemNbr++; } foreach (var socket in m_pollinSockets) { m_pollset[itemNbr] = new SelectItem(socket.Key, PollEvents.PollError | PollEvents.PollIn); itemNbr++; } // Mark this as NOT having any fresh events to attend to, as yet. m_isDirty = false; }