Exemple #1
0
        public void Copy(ref Msg src)
        {
            //  Check the validity of the source.
            if (!src.Check())
            {
                throw NetMQException.Create(ErrorCode.EFAULT);
            }

            Close();

            if (m_type == MsgType.Pool)
            {
                //  One reference is added to shared messages. Non-shared messages
                //  are turned into shared messages and reference count is set to 2.
                if (src.m_flags.HasFlag(MsgFlags.Shared))
                {
                    src.m_atomicCounter.Increase(1);
                }
                else
                {
                    src.m_flags |= MsgFlags.Shared;
                    src.m_atomicCounter.Set(2);
                }
            }

            this = src;
        }
Exemple #2
0
        public void Move(ref Msg src)
        {
            //  Check the validity of the source.
            if (!src.Check())
            {
                throw NetMQException.Create(ErrorCode.EFAULT);
            }

            Close();

            this = src;

            src.InitEmpty();
        }
Exemple #3
0
        public void Recv(ref Msg msg, SendReceiveOptions flags)
        {
            CheckContextTerminated();

            //  Check whether message passed to the function is valid.
            if (!msg.Check())
            {
                throw new FaultException();
            }

            //  Get the message.
            bool isMessageAvailable = XRecv(flags, ref msg);

            //  Once every inbound_poll_rate messages check for signals and process
            //  incoming commands. This happens only if we are not polling altogether
            //  because there are messages available all the time. If poll occurs,
            //  ticks is set to zero and thus we avoid this code.
            //
            //  Note that 'recv' uses different command throttling algorithm (the one
            //  described above) from the one used by 'send'. This is because counting
            //  ticks is more efficient than doing RDTSC all the time.
            if (++m_ticks == Config.InboundPollRate)
            {
                ProcessCommands(0, false);
                m_ticks = 0;
            }

            //  If we have the message, return immediately.
            if (isMessageAvailable)
            {
                ExtractFlags(ref msg);
                return;
            }

            //  If the message cannot be fetched immediately, there are two scenarios.
            //  For non-blocking recv, commands are processed in case there's an
            //  activate_reader command already waiting int a command pipe.
            //  If it's not, return EAGAIN.
            if ((flags & SendReceiveOptions.DontWait) > 0 || m_options.ReceiveTimeout == 0)
            {
                ProcessCommands(0, false);
                m_ticks = 0;

                isMessageAvailable = XRecv(flags, ref msg);
                if (!isMessageAvailable)
                {
                    throw new AgainException();
                }

                ExtractFlags(ref msg);
                return;
            }

            //  Compute the time when the timeout should occur.
            //  If the timeout is infite, don't care.
            int  timeout = m_options.ReceiveTimeout;
            long end     = timeout < 0 ? 0 : (Clock.NowMs() + timeout);

            //  In blocking scenario, commands are processed over and over again until
            //  we are able to fetch a message.
            bool block = (m_ticks != 0);

            while (true)
            {
                ProcessCommands(block ? timeout : 0, false);

                isMessageAvailable = XRecv(flags, ref msg);
                if (isMessageAvailable)
                {
                    m_ticks = 0;
                    break;
                }

                block = true;
                if (timeout > 0)
                {
                    timeout = (int)(end - Clock.NowMs());
                    if (timeout <= 0)
                    {
                        throw new AgainException();
                    }
                }
            }

            ExtractFlags(ref msg);
        }
Exemple #4
0
        public void Send(ref Msg msg, SendReceiveOptions flags)
        {
            CheckContextTerminated();

            //  Check whether message passed to the function is valid.
            if (!msg.Check())
            {
                throw new FaultException();
            }

            //  Process pending commands, if any.
            ProcessCommands(0, true);

            //  Clear any user-visible flags that are set on the message.
            msg.ResetFlags(MsgFlags.More);

            //  At this point we impose the flags on the message.
            if ((flags & SendReceiveOptions.SendMore) > 0)
            {
                msg.SetFlags(MsgFlags.More);
            }

            //  Try to send the message.
            bool isMessageSent = XSend(ref msg, flags);

            if (isMessageSent)
            {
                return;
            }

            //  In case of non-blocking send we'll simply propagate
            //  the error - including EAGAIN - up the stack.
            if ((flags & SendReceiveOptions.DontWait) > 0 || m_options.SendTimeout == 0)
            {
                throw new AgainException();
            }

            //  Compute the time when the timeout should occur.
            //  If the timeout is infite, don't care.
            int  timeout = m_options.SendTimeout;
            long end     = timeout < 0 ? 0 : (Clock.NowMs() + timeout);

            //  Oops, we couldn't send the message. Wait for the next
            //  command, process it and try to send the message again.
            //  If timeout is reached in the meantime, return EAGAIN.
            while (true)
            {
                ProcessCommands(timeout, false);

                isMessageSent = XSend(ref msg, flags);
                if (isMessageSent)
                {
                    break;
                }

                if (timeout > 0)
                {
                    timeout = (int)(end - Clock.NowMs());
                    if (timeout <= 0)
                    {
                        throw new AgainException();
                    }
                }
            }
        }