Exemplo n.º 1
0
        //  Processes commands sent to this socket (if any). If timeout is -1,
        //  returns only after at least one command was processed.
        //  If throttle argument is true, commands are processed at most once
        //  in a predefined time period.
        private void ProcessCommands(int timeout, bool throttle)
        {
            Command cmd;

            if (timeout != 0)
            {
                //  If we are asked to wait, simply ask mailbox to wait.
                cmd = m_mailbox.Recv(timeout);
            }
            else
            {
                //  If we are asked not to wait, check whether we haven't processed
                //  commands recently, so that we can throttle the new commands.

                //  Get the CPU's tick counter. If 0, the counter is not available.
                long tsc = Clock.Rdtsc();

                //  Optimised version of command processing - it doesn't have to check
                //  for incoming commands each time. It does so only if certain time
                //  elapsed since last command processing. Command delay varies
                //  depending on CPU speed: It's ~1ms on 3GHz CPU, ~2ms on 1.5GHz CPU
                //  etc. The optimisation makes sense only on platforms where getting
                //  a timestamp is a very cheap operation (tens of nanoseconds).
                if (tsc != 0 && throttle)
                {
                    //  Check whether TSC haven't jumped backwards (in case of migration
                    //  between CPU cores) and whether certain time have elapsed since
                    //  last command processing. If it didn't do nothing.
                    if (tsc >= m_lastTsc && tsc - m_lastTsc <= Config.MaxCommandDelay)
                    {
                        return;
                    }
                    m_lastTsc = tsc;
                }

                //  Check whether there are any commands pending for this thread.
                cmd = m_mailbox.Recv(0);
            }

            //  Process all the commands available at the moment.
            while (true)
            {
                if (cmd == null)
                {
                    break;
                }

                cmd.Destination.ProcessCommand(cmd);
                cmd = m_mailbox.Recv(0);
            }
            if (m_ctxTerminated)
            {
                throw TerminatingException.Create();
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// This function is called when user invokes zmq_term. If there are
        /// no more sockets open it'll cause all the infrastructure to be shut
        /// down. If there are open sockets still, the deallocation happens
        /// after the last one is closed.
        /// </summary>
        public void Terminate()
        {
            m_disposed = true;

            Monitor.Enter(m_slotSync);

            if (!m_starting)
            {
                //  Check whether termination was already underway, but interrupted and now
                //  restarted.
                bool restarted = m_terminating;
                m_terminating = true;
                Monitor.Exit(m_slotSync);


                //  First attempt to terminate the context.
                if (!restarted)
                {
                    //  First send stop command to sockets so that any blocking calls
                    //  can be interrupted. If there are no sockets we can ask reaper
                    //  thread to stop.
                    Monitor.Enter(m_slotSync);
                    try
                    {
                        for (int i = 0; i != m_sockets.Count; i++)
                        {
                            m_sockets[i].Stop();
                        }
                        if (m_sockets.Count == 0)
                        {
                            m_reaper.Stop();
                        }
                    }
                    finally
                    {
                        Monitor.Exit(m_slotSync);
                    }
                }

                //  Wait till reaper thread closes all the sockets.
                Command cmd = m_termMailbox.Recv(-1);

                Debug.Assert(cmd != null);
                Debug.Assert(cmd.CommandType == CommandType.Done);
                Monitor.Enter(m_slotSync);
                Debug.Assert(m_sockets.Count == 0);
            }
            Monitor.Exit(m_slotSync);

            //  Deallocate the resources.
            Destroy();
        }
Exemplo n.º 3
0
        public void InEvent()
        {
            while (true)
            {
                //  Get the next command. If there is none, exit.
                Command cmd = mailbox.Recv(0);
                if (cmd == null)
                {
                    break;
                }

                //  Process the command.
                cmd.Destination.ProcessCommand(cmd);
            }
        }
Exemplo n.º 4
0
        public void InEvent()
        {
            //  TODO: Do we want to limit number of commands I/O thread can
            //  process in a single go?

            while (true)
            {
                //  Get the next command. If there is none, exit.
                Command cmd = m_mailbox.Recv(0);
                if (cmd == null)
                {
                    break;
                }

                //  Process the command.

                cmd.Destination.ProcessCommand(cmd);
            }
        }