예제 #1
0
파일: Sub.cs 프로젝트: knocte/netmq
        protected override bool XSetSocketOption(ZmqSocketOptions option, Object optval)
        {
            if (option != ZmqSocketOptions.Subscribe && option != ZmqSocketOptions.Unsubscribe)
            {
                ZError.ErrorNumber = (ErrorNumber.EINVAL);
                return false;
            }

            byte[] val;

            if (optval is String)
                val =  Encoding.ASCII.GetBytes ((String)optval);
            else if (optval is byte[])
                val = (byte[]) optval;
            else
                throw new ArgumentException();

            //  Create the subscription message.
            Msg msg = new Msg(val.Length + 1);
            if (option == ZmqSocketOptions.Subscribe)
                msg.Put((byte)1);
            else if (option == ZmqSocketOptions.Unsubscribe)
                msg.Put((byte)0);
            msg.Put (val,1);

            //  Pass it further on in the stack.
            bool rc = base.XSend (msg, 0);
            return rc;
        }
예제 #2
0
파일: Dealer.cs 프로젝트: knocte/netmq
        protected override bool XHasIn()
        {
            //  We may already have a message pre-fetched.
            if (m_prefetched)
                return true;

            //  Try to read the next message to the pre-fetch buffer.
            m_prefetchedMsg = xxrecv(SendRecieveOptions.DontWait);
            if (m_prefetchedMsg == null && ZError.IsError(ErrorNumber.EAGAIN))
                return false;
            m_prefetched = true;
            return true;
        }
예제 #3
0
파일: XSub.cs 프로젝트: knocte/netmq
        static XSub()
        {
            s_sendSubscription = (data, size, arg) => {

                                                       	Pipe pipe = (Pipe) arg;

                                                       	//  Create the subsctription message.
                                                       	Msg msg = new Msg(size + 1);
                                                       	msg.Put((byte)1);
                                                       	msg.Put(data,1, size);

                                                       	//  Send it to the pipe.
                                                       	bool sent = pipe.Write (msg);
                                                       	//  If we reached the SNDHWM, and thus cannot send the subscription, drop
                                                       	//  the subscription message instead. This matches the behaviour of
                                                       	//  zmq_setsockopt(ZMQ_SUBSCRIBE, ...), which also drops subscriptions
                                                       	//  when the SNDHWM is reached.
                                                       	if (!sent)
                                                       		msg.Close ();

            };
        }
예제 #4
0
파일: V1Decoder.cs 프로젝트: knocte/netmq
        private bool OneByteSizeReady()
        {
            //  Message size must not exceed the maximum allowed size.
            if (m_maxmsgsize >= 0)
                if (m_tmpbuf [0] > m_maxmsgsize) {
                    DecodingError ();
                    return false;
                }

            //  in_progress is initialised at this point so in theory we should
            //  close it before calling zmq_msg_init_size, however, it's a 0-byte
            //  message and thus we can treat it as uninitialised...
            m_inProgress = new Msg(m_tmpbuf [0]);

            m_inProgress.SetFlags (m_msgFlags);
            NextStep (m_inProgress.Data , m_inProgress.Size ,MessageReadyState);

            return true;
        }
예제 #5
0
파일: Router.cs 프로젝트: knocte/netmq
        protected override bool XSend(Msg msg, SendRecieveOptions flags)
        {
            //  If this is the first part of the message it's the ID of the
            //  peer to send the message to.
            if (!m_moreOut) {
                Debug.Assert(m_currentOut == null);

                //  If we have malformed message (prefix with no subsequent message)
                //  then just silently ignore it.
                //  TODO: The connections should be killed instead.
                if (msg.HasMore) {

                    m_moreOut = true;

                    //  Find the pipe associated with the identity stored in the prefix.
                    //  If there's no such pipe just silently ignore the message, unless
                    //  mandatory is set.
                    Blob identity = new Blob(msg.Data);
                    Outpipe op = m_outpipes[identity];

                    if (op != null) {
                        m_currentOut = op.Pipe;
                        if (!m_currentOut.CheckWrite ()) {
                            op.Active = false;
                            m_currentOut = null;
                        }
                    } else if (m_mandatory) {
                        m_moreOut = false;
                        ZError.ErrorNumber = (ErrorNumber.EHOSTUNREACH);
                        return false;
                    }
                }

                return true;
            }

            //  Check whether this is the last part of the message.
            m_moreOut = msg.HasMore;

            //  Push the message into the pipe. If there's no out pipe, just drop it.
            if (m_currentOut != null) {
                bool ok = m_currentOut.Write (msg);
                if (!ok)
                    m_currentOut = null;
                else if (!m_moreOut) {
                    m_currentOut.Flush ();
                    m_currentOut = null;
                }
            }
            else {
            }

            //  Detach the message from the data buffer.

            return true;
        }
예제 #6
0
파일: Router.cs 프로젝트: knocte/netmq
        protected override bool XHasIn()
        {
            //  If we are in the middle of reading the messages, there are
            //  definitely more parts available.
            if (m_moreIn)
                return true;

            //  We may already have a message pre-fetched.
            if (m_prefetched)
                return true;

            //  Try to read the next message.
            //  The message, if read, is kept in the pre-fetch buffer.
            Pipe[] pipe = new Pipe[1];
            m_prefetchedMsg = m_fq.RecvPipe (pipe);

            //  It's possible that we receive peer's identity. That happens
            //  after reconnection. The current implementation assumes that
            //  the peer always uses the same identity.
            //  TODO: handle the situation when the peer changes its identity.
            while (m_prefetchedMsg != null && m_prefetchedMsg.IsIdentity )
                m_prefetchedMsg = m_fq.RecvPipe (pipe);

            if (m_prefetchedMsg == null)
                return false;

            Debug.Assert(pipe[0] != null);

            Blob identity = pipe[0].Identity ;
            m_prefetchedId = new Msg(identity.Data);
            m_prefetchedId.SetFlags(MsgFlags.More);

            m_prefetched = true;
            m_identitySent = false;

            return true;
        }
예제 #7
0
파일: ZMQ.cs 프로젝트: knocte/netmq
 private static int SendMsg(SocketBase s, Msg msg, SendRecieveOptions flags)
 {
     int sz = MsgSize(msg);
     bool rc = s.Send(msg, flags);
     if (!rc)
         return -1;
     return sz;
 }
예제 #8
0
파일: ZMQ.cs 프로젝트: knocte/netmq
 public static int ZmqMsgGet(Msg msg, MsgFlags option)
 {
     switch (option)
     {
         case MsgFlags.More:
             return msg.HasMore ? 1 : 0;
         default:
             throw new ArgumentException();
     }
 }
예제 #9
0
파일: ZMQ.cs 프로젝트: knocte/netmq
        public static int Send(SocketBase s, Msg msg, SendRecieveOptions flags)
        {
            int rc = SendMsg(s, msg, flags);
            if (rc < 0)
            {
                return -1;
            }

            return rc;
        }
예제 #10
0
파일: Req.cs 프로젝트: knocte/netmq
        protected override bool XSend(Msg msg, SendRecieveOptions flags)
        {
            //  If we've sent a request and we still haven't got the reply,
            //  we can't send another request.
            if (m_receivingReply) {
                throw new InvalidOperationException("Cannot send another request");
            }

            bool rc;

            //  First part of the request is the request identity.
            if (m_messageBegins) {
                Msg bottom = new Msg();
                bottom.SetFlags (MsgFlags.More);
                rc = base.XSend (bottom, 0);
                if (!rc)
                    return false;
                m_messageBegins = false;
            }

            bool more = msg.HasMore;

            rc = base.XSend (msg, flags);
            if (!rc)
                return rc;

            //  If the request was fully sent, flip the FSM into reply-receiving state.
            if (!more) {
                m_receivingReply = true;
                m_messageBegins = true;
            }

            return true;
        }
예제 #11
0
파일: XSub.cs 프로젝트: knocte/netmq
 private bool Match(Msg msg)
 {
     return m_subscriptions.Check(msg.Data);
 }
예제 #12
0
파일: XSub.cs 프로젝트: knocte/netmq
        protected override bool XSend(Msg msg, SendRecieveOptions flags)
        {
            byte[] data = msg.Data;
            // Malformed subscriptions.
            if (data.Length < 1 || (data[0] != 0 && data[0] != 1)) {
                return false;
            }

            // Process the subscription.
            if (data[0] == 1) {
                if (m_subscriptions.Add (data , 1))
                    return m_dist.SendToAll (msg, flags);
            }
            else {
                if (m_subscriptions.Remove (data, 1))
                    return m_dist.SendToAll (msg, flags);
            }

            return true;
        }
예제 #13
0
파일: XSub.cs 프로젝트: knocte/netmq
        protected override Msg XRecv(SendRecieveOptions flags)
        {
            //  If there's already a message prepared by a previous call to zmq_poll,
            //  return it straight ahead.
            Msg msg;
            if (m_hasMessage) {
                msg = new Msg(m_message);
                m_hasMessage = false;
                m_more = msg.HasMore;
                return msg;
            }

            //  TODO: This can result in infinite loop in the case of continuous
            //  stream of non-matching messages which breaks the non-blocking recv
            //  semantics.
            while (true) {

                //  Get a message using fair queueing algorithm.
                msg = m_fq.Recv ();

                //  If there's no message available, return immediately.
                //  The same when error occurs.
                if (msg == null)
                    return null;

                //  Check whether the message matches at least one subscription.
                //  Non-initial parts of the message are passed
                if (m_more || !m_options.Filter || Match (msg)) {
                    m_more = msg.HasMore;
                    return msg;
                }

                //  Message doesn't match. Pop any remaining parts of the message
                //  from the pipe.
                while (msg.HasMore) {
                    msg = m_fq.Recv ();
                    Debug.Assert(msg != null);
                }
            }
        }
예제 #14
0
파일: XSub.cs 프로젝트: knocte/netmq
        protected override bool XHasIn()
        {
            //  There are subsequent parts of the partly-read message available.
            if (m_more)
                return true;

            //  If there's already a message prepared by a previous call to zmq_poll,
            //  return straight ahead.
            if (m_hasMessage)
                return true;

            //  TODO: This can result in infinite loop in the case of continuous
            //  stream of non-matching messages.
            while (true) {

                //  Get a message using fair queueing algorithm.
                m_message = m_fq.Recv ();

                //  If there's no message available, return immediately.
                //  The same when error occurs.
                if (m_message == null) {
                    Debug.Assert(ZError.IsError(ErrorNumber.EAGAIN));
                    return false;
                }

                //  Check whether the message matches at least one subscription.
                if (!m_options.Filter || Match (m_message)) {
                    m_hasMessage = true;
                    return true;
                }

                //  Message doesn't match. Pop any remaining parts of the message
                //  from the pipe.
                while (m_message.HasMore) {
                    m_message = m_fq.Recv ();
                    Debug.Assert(m_message != null);
                }
            }
        }
예제 #15
0
파일: Rep.cs 프로젝트: knocte/netmq
        protected override bool XSend(Msg msg, SendRecieveOptions flags)
        {
            //  If we are in the middle of receiving a request, we cannot send reply.
            if (!m_sendingReply) {
                throw new InvalidOperationException ("Cannot send another reply");
            }

            bool more = msg.HasMore;

            //  Push message to the reply pipe.
            bool rc = base.XSend (msg, flags);
            if (!rc)
                return rc;

            //  If the reply is complete flip the FSM back to request receiving state.
            if (!more)
                m_sendingReply = false;

            return true;
        }
예제 #16
0
파일: ZMQ.cs 프로젝트: knocte/netmq
 public static int MsgGet(Msg msg)
 {
     return ZmqMsgGet(msg, MsgFlags.More);
 }
예제 #17
0
파일: ZMQ.cs 프로젝트: knocte/netmq
 public static int MsgSize(Msg msg)
 {
     return msg.Size;
 }
예제 #18
0
파일: Req.cs 프로젝트: knocte/netmq
            public override bool PushMsg(Msg msg)
            {
                switch (m_state) {
                    case State.Bottom:
                        if (msg.Flags == MsgFlags.More && msg.Size == 0) {
                            m_state = State.Body;
                            return base.PushMsg (msg);
                        }
                        break;
                    case State.Body:
                        if (msg.Flags == MsgFlags.More)
                            return base.PushMsg (msg);
                        if (msg.Flags == 0) {
                            m_state = State.Bottom;
                            return base.PushMsg (msg);
                        }
                        break;
                    case State.Identity:
                        if (msg.Flags == 0) {
                            m_state = State.Bottom;
                            return base.PushMsg (msg);
                        }
                        break;
                }

                throw new InvalidOperationException(m_state.ToString());
            }
예제 #19
0
파일: ZMQ.cs 프로젝트: knocte/netmq
        public static int Send(SocketBase s, byte[] buf, int len, SendRecieveOptions flags)
        {
            if (s == null || !s.CheckTag())
            {
                throw new InvalidOperationException();
            }

            Msg msg = new Msg(len);
            msg.Put(buf, 0, len);

            int rc = SendMsg(s, msg, flags);
            if (rc < 0)
            {
                return -1;
            }

            return rc;
        }
예제 #20
0
파일: SocketBase.cs 프로젝트: knocte/netmq
 protected virtual bool XSend(Msg msg, SendRecieveOptions flags)
 {
     throw new NotSupportedException("Must Override");
 }
예제 #21
0
파일: ZMQ.cs 프로젝트: knocte/netmq
        // Send multiple messages.
        //
        // If flag bit ZMQ_SNDMORE is set the vector is treated as
        // a single multi-part message, i.e. the last message has
        // ZMQ_SNDMORE bit switched off.
        //
        public int SendIOv(SocketBase s, byte[][] a, int count, SendRecieveOptions flags)
        {
            if (s == null || !s.CheckTag())
            {
                throw new InvalidOperationException();
            }
            int rc = 0;
            Msg msg;

            for (int i = 0; i < count; ++i)
            {
                msg = new Msg(a[i]);
                if (i == count - 1)
                    flags = flags & ~SendRecieveOptions.SendMore;
                rc = SendMsg(s, msg, flags);
                if (rc < 0)
                {
                    rc = -1;
                    break;
                }
            }
            return rc;
        }
예제 #22
0
파일: SocketBase.cs 프로젝트: knocte/netmq
        //  Moves the flags from the message to local variables,
        //  to be later retrieved by getsockopt.
        private void ExtractFlags(Msg msg)
        {
            //  Test whether IDENTITY flag is valid for this socket type.
            if ((msg.Flags & MsgFlags.Identity) != 0)
                Debug.Assert(m_options.RecvIdentity);

            //  Remove MORE flag.
            m_rcvMore = msg.HasMore;
        }
예제 #23
0
파일: Pair.cs 프로젝트: knocte/netmq
        protected override bool XSend(Msg msg, SendRecieveOptions flags)
        {
            if (m_pipe == null || !m_pipe.Write (msg)) {
                ZError.ErrorNumber = (ErrorNumber.EAGAIN);
                return false;
            }

            if ((flags & SendRecieveOptions.SendMore) == 0)
                m_pipe.Flush ();

            //  Detach the original message from the data buffer.

            return true;
        }
예제 #24
0
파일: SocketBase.cs 프로젝트: knocte/netmq
        public bool Connect(String addr)
        {
            if (m_ctxTerminated)
            {
                ZError.ErrorNumber = (ErrorNumber.ETERM);
                return false;
            }

            //  Process pending commands, if any.
            bool brc = ProcessCommands(0, false);
            if (!brc)
                return false;

            //  Parse addr_ string.
            Uri uri;
            try
            {
                uri = new Uri(addr);
            }
            catch (Exception e)
            {
                throw new ArgumentException(addr, e);
            }

            String protocol = uri.Scheme;
            String address = uri.Authority;
            String path = uri.AbsolutePath;
            if (string.IsNullOrEmpty(address))
                address = path;

            CheckProtocol(protocol);

            if (protocol.Equals("inproc"))
            {

                //  TODO: inproc connect is specific with respect to creating pipes
                //  as there's no 'reconnect' functionality implemented. Once that
                //  is in place we should follow generic pipe creation algorithm.

                //  Find the peer endpoint.
                Ctx.Endpoint peer = FindEndpoint(addr);
                if (peer.Socket == null)
                    return false;
                // The total HWM for an inproc connection should be the sum of
                // the binder's HWM and the connector's HWM.
                int sndhwm;
                int rcvhwm;
                if (m_options.SendHighWatermark == 0 || peer.Options.ReceiveHighWatermark == 0)
                    sndhwm = 0;
                else
                    sndhwm = m_options.SendHighWatermark + peer.Options.ReceiveHighWatermark;
                if (m_options.ReceiveHighWatermark == 0 || peer.Options.SendHighWatermark == 0)
                    rcvhwm = 0;
                else
                    rcvhwm = m_options.ReceiveHighWatermark + peer.Options.SendHighWatermark;

                //  Create a bi-directional pipe to connect the peers.
                ZObject[] parents = { this, peer.Socket };
                Pipe[] pipes = { null, null };
                int[] hwms = { sndhwm, rcvhwm };
                bool[] delays = { m_options.DelayOnDisconnect, m_options.DelayOnClose };
                Pipe.Pipepair(parents, pipes, hwms, delays);

                //  Attach local end of the pipe to this socket object.
                AttachPipe(pipes[0]);

                //  If required, send the identity of the peer to the local socket.
                if (peer.Options.RecvIdentity)
                {
                    Msg id = new Msg(peer.Options.IdentitySize);
                    id.Put(peer.Options.Identity, 0, peer.Options.IdentitySize);
                    id.SetFlags(MsgFlags.Identity);
                    bool written = pipes[0].Write(id);
                    Debug.Assert(written);
                    pipes[0].Flush();
                }

                //  If required, send the identity of the local socket to the peer.
                if (m_options.RecvIdentity)
                {
                    Msg id = new Msg(m_options.IdentitySize);
                    id.Put(m_options.Identity, 0, m_options.IdentitySize);
                    id.SetFlags(MsgFlags.Identity);
                    bool written = pipes[1].Write(id);
                    Debug.Assert(written);
                    pipes[1].Flush();
                }

                //  Attach remote end of the pipe to the peer socket. Note that peer's
                //  seqnum was incremented in find_endpoint function. We don't need it
                //  increased here.
                SendBind(peer.Socket, pipes[1], false);

                // Save last endpoint URI
                m_options.LastEndpoint = addr;

                return true;
            }

            //  Choose the I/O thread to run the session in.
            IOThread ioThread = ChooseIOThread(m_options.Affinity);
            if (ioThread == null)
            {
                throw new ArgumentException("Empty IO Thread");
            }
            Address paddr = new Address(protocol, address);

            //  Resolve address (if needed by the protocol)
            if (protocol.Equals("tcp"))
            {
                paddr.Resolved = (new TcpAddress());
                paddr.Resolved.Resolve(
                    address, m_options.IPv4Only);
            }
            else if (protocol.Equals("Ipc"))
            {
                paddr.Resolved = (new IpcAddress());
                paddr.Resolved.Resolve(address, true);
            }
            //  Create session.
            SessionBase session = SessionBase.Create(ioThread, true, this,
                                                                                                m_options, paddr);
            Debug.Assert(session != null);

            //  PGM does not support subscription forwarding; ask for all data to be
            //  sent to this pipe.
            bool icanhasall = false;
            if (protocol.Equals("pgm") || protocol.Equals("epgm"))
                icanhasall = true;

            if (!m_options.DelayAttachOnConnect || icanhasall)
            {
                //  Create a bi-directional pipe.
                ZObject[] parents = { this, session };
                Pipe[] pipes = { null, null };
                int[] hwms = { m_options.SendHighWatermark, m_options.ReceiveHighWatermark };
                bool[] delays = { m_options.DelayOnDisconnect, m_options.DelayOnClose };
                Pipe.Pipepair(parents, pipes, hwms, delays);

                //  Attach local end of the pipe to the socket object.
                AttachPipe(pipes[0], icanhasall);

                //  Attach remote end of the pipe to the session object later on.
                session.AttachPipe(pipes[1]);
            }

            // Save last endpoint URI
            m_options.LastEndpoint = paddr.ToString();

            AddEndpoint(addr, session);
            return true;
        }
예제 #25
0
파일: Router.cs 프로젝트: knocte/netmq
        protected override Msg XRecv(SendRecieveOptions flags)
        {
            Msg msg = null;
            if (m_prefetched) {
                if (!m_identitySent) {
                    msg = m_prefetchedId;
                    m_prefetchedId = null;
                    m_identitySent = true;
                }
                else {
                    msg = m_prefetchedMsg;
                    m_prefetchedMsg = null;
                    m_prefetched = false;
                }
                m_moreIn = msg.HasMore;
                return msg;
            }

            Pipe[] pipe = new Pipe[1];
            msg = m_fq.RecvPipe (pipe);

            //  It's possible that we receive peer's identity. That happens
            //  after reconnection. The current implementation assumes that
            //  the peer always uses the same identity.
            //  TODO: handle the situation when the peer changes its identity.
            while (msg != null && msg.IsIdentity )
                msg = m_fq.RecvPipe (pipe);

            if (msg == null)
                return null;

            Debug.Assert(pipe[0] != null);

            //  If we are in the middle of reading a message, just return the next part.
            if (m_moreIn)
                m_moreIn = msg.HasMore;
            else {
                //  We are at the beginning of a message.
                //  Keep the message part we have in the prefetch buffer
                //  and return the ID of the peer instead.
                m_prefetchedMsg = msg;

                m_prefetched = true;

                Blob identity = pipe[0].Identity;
                msg = new Msg(identity.Data);
                msg.SetFlags(MsgFlags.More);
                m_identitySent = true;
            }

            return msg;
        }
예제 #26
0
파일: SocketBase.cs 프로젝트: knocte/netmq
        public bool Send(Msg msg, SendRecieveOptions flags)
        {
            if (m_ctxTerminated)
            {
                ZError.ErrorNumber = (ErrorNumber.ETERM);
                return false;
            }

            //  Check whether message passed to the function is valid.
            if (msg == null)
            {
                ZError.ErrorNumber = (ErrorNumber.EFAULT);
                throw new ArgumentException();
            }

            //  Process pending commands, if any.
            bool rc = ProcessCommands(0, true);
            if (!rc)
                return false;

            //  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 & SendRecieveOptions.SendMore) > 0)
                msg.SetFlags(MsgFlags.More);

            //  Try to send the message.
            rc = XSend(msg, flags);
            if (rc)
                return true;
            if (!ZError.IsError(ErrorNumber.EAGAIN))
                return false;

            //  In case of non-blocking send we'll simply propagate
            //  the error - including EAGAIN - up the stack.
            if ((flags & SendRecieveOptions.DontWait) > 0 || m_options.SendTimeout == 0)
                return false;

            //  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)
            {
                if (!ProcessCommands(timeout, false))
                    return false;

                rc = XSend(msg, flags);
                if (rc)
                    break;

                if (!ZError.IsError(ErrorNumber.EAGAIN))
                    return false;

                if (timeout > 0)
                {
                    timeout = (int)(end - Clock.NowMs());
                    if (timeout <= 0)
                    {
                        ZError.ErrorNumber = (ErrorNumber.EAGAIN);
                        return false;
                    }
                }
            }
            return true;
        }
예제 #27
0
파일: Router.cs 프로젝트: knocte/netmq
        public Router(Ctx parent, int tid, int sid)
            : base(parent, tid, sid)
        {
            m_prefetched = false;
            m_identitySent = false;
            m_moreIn = false;
            m_currentOut = null;
            m_moreOut = false;
            m_nextPeerId = Utils.GenerateRandom ();
            m_mandatory = false;

            m_options.SocketType = ZmqSocketType.Router;

            m_fq = new FQ();
            m_prefetchedId = new Msg();
            m_prefetchedMsg = new Msg();

            m_anonymousPipes = new HashSet<Pipe>();
            m_outpipes = new Dictionary<Blob, Outpipe>();

            //  TODO: Uncomment the following line when ROUTER will become true ROUTER
            //  rather than generic router socket.
            //  If peer disconnect there's noone to send reply to anyway. We can drop
            //  all the outstanding requests from that peer.
            //  options.delay_on_disconnect = false;

            m_options.RecvIdentity = true;
        }
예제 #28
0
파일: LB.cs 프로젝트: knocte/netmq
        public bool Send(Msg msg, SendRecieveOptions flags)
        {
            //  Drop the message if required. If we are at the end of the message
            //  switch back to non-dropping mode.
            if (m_dropping) {

                m_more = msg.HasMore;
                m_dropping = m_more;

                msg.Close ();
                return true;
            }

            while (m_active > 0) {
                if (m_pipes[m_current].Write (msg))
                    break;

                Debug.Assert(!m_more);
                m_active--;
                if (m_current < m_active)
                    Utils.Swap (m_pipes, m_current, m_active);
                else
                    m_current = 0;
            }

            //  If there are no pipes we cannot send the message.
            if (m_active == 0) {
                ZError.ErrorNumber = ErrorNumber.EAGAIN;
                return false;
            }

            //  If it's part of the message we can fluch it downstream and
            //  continue round-robinning (load balance).
            m_more = msg.HasMore;
            if (!m_more) {
                m_pipes[m_current].Flush();
                if (m_active > 1)
                    m_current = (m_current + 1) % m_active;
            }

            return true;
        }
예제 #29
0
파일: V1Decoder.cs 프로젝트: knocte/netmq
        private bool EightByteSizeReady()
        {
            //  The payload size is encoded as 64-bit unsigned integer.
            //  The most significant byte comes first.

            long msg_size = m_tmpbuf.GetLong(0);

            //  Message size must not exceed the maximum allowed size.
            if (m_maxmsgsize >= 0)
                if (msg_size > m_maxmsgsize) {
                    DecodingError ();
                    return false;
                }

            //  Message size must fit within range of size_t data type.
            if (msg_size > int.MaxValue) {
                DecodingError ();
                return false;
            }

            //  in_progress is initialised at this point so in theory we should
            //  close it before calling init_size, however, it's a 0-byte
            //  message and thus we can treat it as uninitialised.
            m_inProgress = new Msg ((int) msg_size);

            m_inProgress.SetFlags (m_msgFlags);
            NextStep (m_inProgress.Data , m_inProgress.Size, MessageReadyState);

            return true;
        }
예제 #30
0
파일: Push.cs 프로젝트: knocte/netmq
 protected override bool XSend(Msg msg, SendRecieveOptions flags)
 {
     return lb.Send (msg, flags);
 }