public void ShouldAllowInfinitePolling() { Ctx contextNew = ZMQ.CtxNew(); SocketBase receiver = ZMQ.Socket(contextNew, ZmqSocketType.Dealer); ZMQ.Bind(receiver, "inproc://test"); Task.Factory.StartNew(() => { Thread.Sleep(500); SocketBase sender = ZMQ.Socket(contextNew, ZmqSocketType.Dealer); ZMQ.Connect(sender, "inproc://test"); ZMQ.Send(sender, "ping", SendReceiveOptions.None); ZMQ.Close(sender); }); var pollItems = new PollItem[] { new PollItem(receiver, PollEvents.PollIn) }; Assert.DoesNotThrow(() => ZMQ.Poll(pollItems, -1)); var msg = ZMQ.Recv(receiver, SendReceiveOptions.DontWait); var actual = Encoding.ASCII.GetString(msg.Data, 0, msg.Size); Assert.AreEqual("ping", actual); ZMQ.Close(receiver); ZMQ.Term(contextNew); }
/// <summary> /// Wait until message is ready to be received from the socket or until timeout is reached /// </summary> /// <param name="timeout"></param> /// <returns></returns> public bool Poll(TimeSpan timeout) { PollEvents events = GetPollEvents(); PollItem item = new PollItem(m_socketHandle, events); PollItem[] items = new PollItem[] { item }; ZMQ.Poll(items, (int)timeout.TotalMilliseconds); if (item.ResultEvent.HasFlag(PollEvents.PollError) && !IgnoreErrors) { Errors++; if (Errors > 1) { throw new ErrorPollingException("Error while polling", this); } } else { Errors = 0; } InvokeEvents(this, item.ResultEvent); return(items[0].ResultEvent != PollEvents.None); }
public void RunPipeline(Sockets.PairSocket shim) { m_pipe = shim; shim.SignalOK(); while (!m_terminated) { PollItem[] pollItems = new PollItem[] { new PollItem(m_pipe.SocketHandle, PollEvents.PollIn), new PollItem(m_udpSocket, PollEvents.PollIn), }; long timeout = -1; if (m_transmit != null) { timeout = m_pingAt - Clock.NowMs(); if (timeout < 0) { timeout = 0; } } ZMQ.Poll(pollItems, m_udpSocket != null ? 2 : 1, (int)timeout); if (pollItems[0].ResultEvent.HasFlag(PollEvents.PollIn)) { HandlePipe(); } if (pollItems[1].ResultEvent.HasFlag(PollEvents.PollIn)) { HandleUdp(); } if (m_transmit != null && Clock.NowMs() > m_pingAt) { SendUdpFrame(m_transmit); m_pingAt = Clock.NowMs() + m_interval; } } m_udpSocket.Dispose(); }
public static NetMQMessage ReceiveMessage(this NetMQSocket socket, TimeSpan timeout) { var item = new PollItem(socket.SocketHandle, PollEvents.PollIn); var items = new[] { item }; ZMQ.Poll(items, (int)timeout.TotalMilliseconds); if (item.ResultEvent.HasFlag(PollEvents.PollError) && !socket.IgnoreErrors) { throw new ErrorPollingException("Error while polling", socket); } if (!item.ResultEvent.HasFlag(PollEvents.PollIn)) { return(null); } var msg = socket.ReceiveMessage(); return(msg); }
private void PollWhile(Func <bool> condition) { if (m_disposed) { throw new ObjectDisposedException("Poller is disposed"); } if (m_isStarted) { throw new InvalidOperationException("Poller is started"); } if (Thread.CurrentThread.Name == null) { Thread.CurrentThread.Name = "NetMQPollerThread"; } m_isStoppedEvent.Reset(); m_isStarted = true; try { // the sockets may have been created in another thread, to make sure we can fully use them we do full memory barried // at the begining of the loop Thread.MemoryBarrier(); // Recalculate all timers now foreach (NetMQTimer netMQTimer in m_timers) { if (netMQTimer.Enable) { netMQTimer.When = Clock.NowMs() + netMQTimer.Interval; } } while (condition()) { if (m_isDirty) { RebuildPollset(); } var pollStart = Clock.NowMs(); var timeout = TicklessTimer(); var nbEvents = ZMQ.Poll(m_pollset, m_pollSize, timeout); // Get the expected end time in case we time out. This looks redundant but, unfortunately, // it happens that Poll takes slightly less than the requested time and 'Clock.NowMs() >= timer.When' // may not true, even if it is supposed to be. In other words, even when Poll times out, it happens // that 'Clock.NowMs() < pollStart + timeout' var expectedPollEnd = nbEvents == 0 ? pollStart + timeout : -1; // that way we make sure we can continue the loop if new timers are added. // timers cannot be removed int timersCount = m_timers.Count; for (int i = 0; i < timersCount; i++) { var timer = m_timers[i]; if ((Clock.NowMs() >= timer.When || expectedPollEnd >= timer.When) && timer.When != -1) { timer.InvokeElapsed(this); if (timer.Enable) { timer.When = timer.Interval + Clock.NowMs(); } } } for (int itemNbr = 0; itemNbr < m_pollSize; itemNbr++) { PollItem item = m_pollset[itemNbr]; if (item.Socket != null) { NetMQSocket socket = m_pollact[itemNbr] as NetMQSocket; if (item.ResultEvent.HasFlag(PollEvents.PollError) && !socket.IgnoreErrors) { socket.Errors++; if (socket.Errors > 1) { RemoveSocket(socket); item.ResultEvent = PollEvents.None; } } else { socket.Errors = 0; } if (item.ResultEvent != PollEvents.None) { socket.InvokeEvents(this, item.ResultEvent); } } else { if (item.ResultEvent.HasFlag(PollEvents.PollError) || item.ResultEvent.HasFlag(PollEvents.PollIn)) { Action <Socket> action; if (m_pollinSockets.TryGetValue(item.FileDescriptor, out action)) { action(item.FileDescriptor); } } } } if (m_zombies.Any()) { // Now handle any timer zombies // This is going to be slow if we have many zombies foreach (NetMQTimer netMQTimer in m_zombies) { m_timers.Remove(netMQTimer); } m_zombies.Clear(); } } } finally { m_isStoppedEvent.Set(); foreach (var socket in m_sockets.ToList()) { RemoveSocket(socket); } } }
public void Start() { Thread.CurrentThread.Name = "NetMQPollerThread"; m_isStoppedEvent.Reset(); m_isStarted = true; try { // the sockets may have been created in another thread, to make sure we can fully use them we do full memory barried // at the begining of the loop Thread.MemoryBarrier(); // Recalculate all timers now foreach (NetMQTimer netMQTimer in m_timers) { if (netMQTimer.Enable) { netMQTimer.When = Clock.NowMs() + netMQTimer.Interval; } } while (!m_cancellationTokenSource.IsCancellationRequested) { if (m_isDirty) { RebuildPollset(); } ZMQ.Poll(m_pollset, m_pollSize, TicklessTimer()); // that way we make sure we can continue the loop if new timers are added. // timers cannot be removed int timersCount = m_timers.Count; for (int i = 0; i < timersCount; i++) { var timer = m_timers[i]; if (Clock.NowMs() >= timer.When && timer.When != -1) { timer.InvokeElapsed(this); if (timer.Enable) { timer.When = timer.Interval + Clock.NowMs(); } } } for (int itemNbr = 0; itemNbr < m_pollSize; itemNbr++) { NetMQSocket socket = m_pollact[itemNbr]; PollItem item = m_pollset[itemNbr]; if (item.ResultEvent.HasFlag(PollEvents.PollError) && !socket.IgnoreErrors) { socket.Errors++; if (socket.Errors > 1) { RemoveSocket(socket); item.ResultEvent = PollEvents.None; } } else { socket.Errors = 0; } if (item.ResultEvent != PollEvents.None) { socket.InvokeEvents(this, item.ResultEvent); } } if (m_zombies.Any()) { // Now handle any timer zombies // This is going to be slow if we have many zombies foreach (NetMQTimer netMQTimer in m_zombies) { m_timers.Remove(netMQTimer); } m_zombies.Clear(); } } } finally { m_isStoppedEvent.Set(); } }