Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        /// <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);
        }
Ejemplo n.º 3
0
            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();
            }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
        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);
                }
            }
        }
Ejemplo n.º 6
0
        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();
            }
        }