/// <summary> /// Unless this socket is closed, /// based upon the given PollEvents - raise the m_receiveReady event if PollIn is set, /// and m_sendReady if PollOut is set. /// </summary> /// <param name="sender">what to use as the source of the events</param> /// <param name="events">the given PollEvents that dictates when of the two events to raise</param> internal void InvokeEvents(object sender, PollEvents events) { if (m_isClosed) { return; } m_socketEventArgs.Init(events); if (events.HasIn()) { var temp = m_receiveReady; if (temp != null) { temp(sender, m_socketEventArgs); } } if (events.HasOut()) { var temp = m_sendReady; if (temp != null) { temp(sender, m_socketEventArgs); } } }
/// <summary> /// Unless this socket is closed, /// based upon the given PollEvents - raise the m_receiveReady event if PollIn is set, /// and m_sendReady if PollOut is set. /// </summary> /// <param name="sender">what to use as the source of the events</param> /// <param name="events">the given PollEvents that dictates when of the two events to raise</param> internal void InvokeEvents(object sender, PollEvents events) { if (m_isClosed != 0) { return; } m_socketEventArgs.Init(events); if (events.HasIn()) { if (m_receiveReady != null) { m_receiveReady.Invoke(sender, m_socketEventArgs); } } if (events.HasOut()) { if (m_sendReady != null) { m_sendReady.Invoke(sender, m_socketEventArgs); } } }
/// <summary> /// Unless this socket is closed, /// based upon the given PollEvents - raise the m_receiveReady event if PollIn is set, /// and m_sendReady if PollOut is set. /// </summary> /// <param name="sender">what to use as the source of the events</param> /// <param name="events">the given PollEvents that dictates when of the two events to raise</param> internal void InvokeEvents(object sender, PollEvents events) { if (this.m_isClosed) { return; } this.m_socketEventArgs.Init(events); if (events.HasIn()) { this.m_receiveReady?.Invoke(sender, this.m_socketEventArgs); } if (events.HasOut()) { this.m_sendReady?.Invoke(sender, this.m_socketEventArgs); } }
/// <summary> /// Initialise the ReceiveReady and SendReady flags from the given PollEvents value. /// </summary> /// <param name="events">a PollEvents value that indicates whether the socket is ready to send or receive without blocking</param> internal void Init(PollEvents events) { IsReadyToReceive = events.HasIn(); IsReadyToSend = events.HasOut(); }
/// <summary> /// Select on NetMQSocket or Socket, similar behavior to Socket.Select. /// </summary> /// <param name="items">Items to select on (must not be null)</param> /// <param name="itemsCount">Number of items in the array to select on</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([NotNull] Item[] items, int itemsCount, long timeout) { if (items == null) { throw new ArgumentNullException(nameof(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; } } this.m_checkRead.Clear(); this.m_checkWrite.Clear(); this.m_checkError.Clear(); for (int i = 0; i < itemsCount; i++) { Item pollItem = items[i]; if (pollItem.Socket != null) { if (pollItem.Event != PollEvents.None && pollItem.Socket.SocketHandle.Handle.Connected) { this.m_checkRead.Add(pollItem.Socket.SocketHandle.Handle); } } else { if (pollItem.Event.HasIn()) { this.m_checkRead.Add(pollItem.FileDescriptor); } if (pollItem.Event.HasOut()) { this.m_checkWrite.Add(pollItem.FileDescriptor); } } } try { SocketUtility.Select(this.m_checkRead, this.m_checkWrite, this.m_checkError, (int)currentTimeoutMicroSeconds); } catch (SocketException x) { #if DEBUG string textOfListRead = StringLib.AsString(this.m_checkRead); string textOfListWrite = StringLib.AsString(this.m_checkWrite); string textOfListError = StringLib.AsString(this.m_checkError); string xMsg = $"In Selector.Select, Socket.Select({textOfListRead}, {textOfListWrite}, {textOfListError}, {currentTimeoutMicroSeconds}) threw a SocketException: {x.Message}"; Debug.WriteLine(xMsg); throw new FaultException(x, xMsg); #else throw new FaultException(innerException: x, message: "Within SocketUtility.Select"); #endif } for (int i = 0; i < itemsCount; i++) { Item selectItem = items[i]; selectItem.ResultEvent = PollEvents.None; if (selectItem.Socket != null) { PollEvents 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 (this.m_checkRead.Contains(selectItem.FileDescriptor)) { selectItem.ResultEvent |= PollEvents.PollIn; } if (this.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); }