Beispiel #1
0
        protected override void XAttachPipe(Pipe pipe, bool icanhasall)
        {
            Debug.Assert(pipe != null);

            //  ZMQ_PAIR socket can only be connected to a single peer.
            //  The socket rejects any further connection requests.
            if (m_pipe == null)
                m_pipe = pipe;
            else
                pipe.Terminate (false);
        }
Beispiel #2
0
        //  Activates pipe that have previously reached high watermark.
        public void Activated(Pipe pipe)
        {
            //  Move the pipe from passive to eligible state.
            Utils.Swap (m_pipes, m_pipes.IndexOf (pipe), m_eligible);
            m_eligible++;

            //  If there's no message being sent at the moment, move it to
            //  the active state.
            if (!m_more) {
                Utils.Swap (m_pipes, m_eligible - 1, m_active);
                m_active++;
            }
        }
Beispiel #3
0
        public Stream(Ctx parent, int threadId, int sid)
            : base(parent, threadId, sid)
        {
            m_prefetched = false;
              m_identitySent = false;
              m_currentOut = null;
              m_moreOut = false;
              m_nextPeerId = Utils.GenerateRandom();

              m_options.SocketType = ZmqSocketType.Stream;

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

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

              m_options.RawSocket = true;
        }
Beispiel #4
0
        protected void SendActivateWrite(Pipe destination,
		                                    long msgsRead)
        {
            Command cmd = new Command(destination, CommandType.ActivateWrite, msgsRead);
            SendCommand (cmd);
        }
Beispiel #5
0
 protected virtual void ProcessBind(Pipe pipe)
 {
     throw new NotSupportedException();
 }
Beispiel #6
0
        protected override void XTerminated(Pipe pipe)
        {
            //  Remove the pipe from the trie. If there are topics that nobody
            //  is interested in anymore, send corresponding unsubscriptions
            //  upstream.

            m_subscriptions.RemoveHelper(pipe, s_SendUnsubscription, this);

            m_dist.Terminated(pipe);
        }
Beispiel #7
0
        protected override void XAttachPipe(Pipe pipe, bool icanhasall)
        {
            Debug.Assert(pipe != null);
            m_dist.Attach(pipe);

            //  If icanhasall_ is specified, the caller would like to subscribe
            //  to all data on this pipe, implicitly.
            if (icanhasall)
                m_subscriptions.Add(null, pipe);

            //  The pipe is active when attached. Let's read the subscriptions from
            //  it, if any.
            XReadActivated(pipe);
        }
Beispiel #8
0
 protected override void XAttachPipe(Pipe pipe, bool icanhasall)
 {
     Debug.Assert(pipe != null);
     lb.Attach (pipe);
 }
Beispiel #9
0
        public SessionBase(IOThread ioThread, bool connect,
                                             SocketBase socket, Options options, Address addr)
            : base(ioThread, options)
        {
            m_ioObject = new IOObject(ioThread);

            m_connect = connect;
            m_pipe = null;
            m_incompleteIn = false;
            m_pending = false;
            m_engine = null;
            m_socket = socket;
            m_ioThread = ioThread;
            m_hasLingerTimer = false;
            m_identitySent = false;
            m_identityReceived = false;
            m_addr = addr;

            if (options.RawSocket)
            {
                m_identitySent = true;
                m_identityReceived = true;
            }

            m_terminatingPipes = new HashSet<Pipe>();
        }
Beispiel #10
0
 /// <summary> <see cref="PipePair"/> uses this function to let us know about the peer pipe object. </summary>
 /// <param name="peer">The peer to be assigned.</param>
 private void SetPeer(Pipe peer)
 {
     //  Peer can be set once only.
     Debug.Assert(peer != null);
     m_peer = peer;
 }
Beispiel #11
0
 public Outpipe(Pipe pipe, bool active)
 {
     Pipe   = pipe;
     Active = active;
 }
Beispiel #12
0
        private bool IdentifyPeer(Pipe pipe)
        {
            Blob identity;

            if (m_options.RawSocket)
            {
                // Always assign identity for raw-socket
                byte[] buf = new byte[5];
                buf[0] = 0;
                byte[] result = BitConverter.GetBytes(m_nextPeerId++);
                Buffer.BlockCopy(result, 0, buf, 1, 4);
                identity = new Blob(buf, buf.Length);
            }
            else
            {
                //  Pick up handshake cases and also case where next identity is set

                Msg msg = new Msg();
                msg.InitEmpty();

                bool ok = pipe.Read(ref msg);

                if (!ok)
                {
                    return(false);
                }

                if (msg.Size == 0)
                {
                    //  Fall back on the auto-generation
                    byte[] buf = new byte[5];

                    buf[0] = 0;

                    byte[] result = BitConverter.GetBytes(m_nextPeerId++);

                    Buffer.BlockCopy(result, 0, buf, 1, 4);
                    identity = new Blob(buf, buf.Length);

                    msg.Close();
                }
                else
                {
                    identity = new Blob(msg.Data, msg.Size);

                    //  Ignore peers with duplicate ID.
                    if (m_outpipes.ContainsKey(identity))
                    {
                        msg.Close();
                        return(false);
                    }

                    msg.Close();
                }
            }

            pipe.Identity = identity;
            //  Add the record into output pipes lookup table
            Outpipe outpipe = new Outpipe(pipe, true);

            m_outpipes.Add(identity, outpipe);

            return(true);
        }
Beispiel #13
0
        protected override bool XRecv(SendReceiveOptions flags, ref Msg msg)
        {
            if (m_prefetched)
            {
                if (!m_identitySent)
                {
                    msg.Move(ref m_prefetchedId);
                    m_identitySent = true;
                }
                else
                {
                    msg.Move(ref m_prefetchedMsg);
                    m_prefetched = false;
                }
                m_moreIn = msg.HasMore;
                return(true);
            }

            Pipe[] pipe = new Pipe[1];

            bool isMessageAvailable = m_fq.RecvPipe(pipe, ref msg);

            //  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 (isMessageAvailable && msg.IsIdentity)
            {
                isMessageAvailable = m_fq.RecvPipe(pipe, ref msg);
            }

            if (!isMessageAvailable)
            {
                return(false);
            }

            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.Move(ref msg);

                m_prefetched = true;

                Blob identity = pipe[0].Identity;
                msg.InitPool(identity.Size);
                msg.Put(identity.Data, 0, identity.Size);
                msg.SetFlags(MsgFlags.More);

                m_identitySent = true;
            }

            return(true);
        }
Beispiel #14
0
        protected override bool XSend(ref Msg msg, SendReceiveOptions 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, msg.Size);
                    Outpipe op;

                    if (m_outpipes.TryGetValue(identity, out op))
                    {
                        m_currentOut = op.Pipe;
                        if (!m_currentOut.CheckWrite())
                        {
                            op.Active    = false;
                            m_currentOut = null;
                            if (m_mandatory)
                            {
                                m_moreOut = false;
                                return(false);
                            }
                        }
                    }
                    else if (m_mandatory)
                    {
                        m_moreOut = false;
                        throw NetMQException.Create(ErrorCode.EHOSTUNREACH);
                    }
                }

                //  Detach the message from the data buffer.
                msg.Close();
                msg.InitEmpty();

                return(true);
            }

            if (m_options.RawSocket)
            {
                msg.ResetFlags(MsgFlags.More);
            }

            //  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)
            {
                // Close the remote connection if user has asked to do so
                // by sending zero length message.
                // Pending messages in the pipe will be dropped (on receiving term- ack)
                if (m_rawSocket && msg.Size == 0)
                {
                    m_currentOut.Terminate(false);
                    msg.Close();
                    msg.InitEmpty();
                    m_currentOut = null;
                    return(true);
                }

                bool ok = m_currentOut.Write(ref msg);
                if (!ok)
                {
                    m_currentOut = null;
                }
                else if (!m_moreOut)
                {
                    m_currentOut.Flush();
                    m_currentOut = null;
                }
            }
            else
            {
                msg.Close();
            }

            //  Detach the message from the data buffer.
            msg.InitEmpty();

            return(true);
        }
Beispiel #15
0
        protected void SendBind(Own destination, Pipe pipe,
		                          bool incSeqnum)
        {
            if (incSeqnum)
                destination.IncSeqnum ();

            Command cmd = new Command(destination, CommandType.Bind, pipe);
            SendCommand (cmd);
        }
Beispiel #16
0
 protected void SendPipeTermAck(Pipe destination)
 {
     Command cmd = new Command(destination, CommandType.PipeTermAck);
     SendCommand (cmd);
 }
Beispiel #17
0
 //  Removes the pipe from the distributor object.
 public void Terminated(Pipe pipe)
 {
     //  Remove the pipe from the list; adjust number of matching, active and/or
     //  eligible pipes accordingly.
     if (m_pipes.IndexOf (pipe) < m_matching)
         m_matching--;
     if (m_pipes.IndexOf (pipe) < m_active)
         m_active--;
     if (m_pipes.IndexOf (pipe) < m_eligible)
         m_eligible--;
     m_pipes.Remove(pipe);
 }
Beispiel #18
0
 protected override void XReadActivated(Pipe pipe)
 {
     m_fq.Activated(pipe);
 }
Beispiel #19
0
 //  Write the message to the pipe. Make the pipe inactive if writing
 //  fails. In such a case false is returned.
 private bool Write(Pipe pipe, Msg msg)
 {
     if (!pipe.Write (msg)) {
         Utils.Swap(m_pipes, m_pipes.IndexOf (pipe), m_matching - 1);
         m_matching--;
         Utils.Swap(m_pipes, m_pipes.IndexOf (pipe), m_active - 1);
         m_active--;
         Utils.Swap(m_pipes, m_active, m_eligible - 1);
         m_eligible--;
         return false;
     }
     if (!msg.HasMore)
         pipe.Flush ();
     return true;
 }
Beispiel #20
0
 protected override void XReadActivated(Pipe pipe)
 {
     m_fq.Activated (pipe);
 }
Beispiel #21
0
 //  Adds the pipe to the distributor object.
 public void Attach(Pipe pipe)
 {
     //  If we are in the middle of sending a message, we'll add new pipe
     //  into the list of eligible pipes. Otherwise we add it to the list
     //  of active pipes.
     if (m_more) {
         m_pipes.Add (pipe);
         //pipes.swap (eligible, pipes.size () - 1);
         Utils.Swap(m_pipes, m_eligible, m_pipes.Count - 1);
         m_eligible++;
     }
     else {
         m_pipes.Add (pipe);
         //pipes.swap (active, pipes.size () - 1);
         Utils.Swap(m_pipes, m_active, m_pipes.Count - 1);
         m_active++;
         m_eligible++;
     }
 }
Beispiel #22
0
 protected override void XTerminated(Pipe pipe)
 {
     lb.Terminated (pipe);
 }
Beispiel #23
0
 //  To be used once only, when creating the session.
 public void AttachPipe(Pipe pipe)
 {
     Debug.Assert(!IsTerminating);
     Debug.Assert(m_pipe == null);
     Debug.Assert(pipe != null);
     m_pipe = pipe;
     m_pipe.SetEventSink(this);
 }
Beispiel #24
0
        protected override void XReadActivated(Pipe pipe)
        {
            //  There are some subscriptions waiting. Let's process them.
            Msg sub;
            while ((sub = pipe.Read()) != null)
            {

                //  Apply the subscription to the trie.
                byte[] data = sub.Data;
                int size = sub.Size;
                if (size > 0 && (data[0] == 0 || data[0] == 1))
                {
                    bool unique;
                    if (data[0] == 0)
                        unique = m_subscriptions.Remove(data, 1, pipe);
                    else
                        unique = m_subscriptions.Add(data, 1, pipe);

                    //  If the subscription is not a duplicate, store it so that it can be
                    //  passed to used on next recv call.
                    if (m_options.SocketType == ZmqSocketType.Xpub && (unique || m_verbose))
                        m_pending.Enqueue(new Blob(sub.Data));
                }
            }
        }
Beispiel #25
0
 public void Hiccuped(Pipe pipe)
 {
     //  Hiccups are always sent from session to socket, not the other
     //  way round.
     throw new NotSupportedException("Must Override");
 }
Beispiel #26
0
 protected override void XWriteActivated(Pipe pipe)
 {
     m_dist.Activated(pipe);
 }
Beispiel #27
0
        public void ReadActivated(Pipe pipe)
        {
            // Skip activating if we're detaching this pipe
            if (m_pipe != pipe)
            {
                Debug.Assert(m_terminatingPipes.Contains(pipe));
                return;
            }

            if (m_engine != null)
                m_engine.ActivateOut();
            else
                m_pipe.CheckRead();
        }
Beispiel #28
0
 protected void SendActivateRead(Pipe destination)
 {
     Command cmd = new Command(destination, CommandType.ActivateRead);
     SendCommand (cmd);
 }
Beispiel #29
0
        public void Terminated(Pipe pipe)
        {
            //  Drop the reference to the deallocated pipe.
            Debug.Assert(m_pipe == pipe || m_terminatingPipes.Contains(pipe));

            if (m_pipe == pipe)
                // If this is our current pipe, remove it
                m_pipe = null;
            else
                // Remove the pipe from the detached pipes set
                m_terminatingPipes.Remove(pipe);

            if (!IsTerminating && m_options.RawSocket)
            {
                if (m_engine != null)
                {
                    m_engine.Terminate();
                    m_engine = null;
                }
                Terminate();
            }

            //  If we are waiting for pending messages to be sent, at this point
            //  we are sure that there will be no more messages and we can proceed
            //  with termination safely.
            if (m_pending && m_pipe == null && m_terminatingPipes.Count == 0)
                ProceedWithTerm();
        }
Beispiel #30
0
 protected void SendBind(Own destination, Pipe pipe)
 {
     SendBind(destination, pipe, true);
 }
Beispiel #31
0
        public void WriteActivated(Pipe pipe)
        {
            // Skip activating if we're detaching this pipe
            if (m_pipe != pipe)
            {
                Debug.Assert(m_terminatingPipes.Contains(pipe));
                return;
            }

            if (m_engine != null)
                m_engine.ActivateIn();
        }
Beispiel #32
0
 protected void SendHiccup(Pipe destination, Object pipe)
 {
     Command cmd = new Command(destination, CommandType.Hiccup, pipe);
     SendCommand (cmd);
 }
Beispiel #33
0
        protected override void ProcessAttach(IEngine engine)
        {
            Debug.Assert(engine != null);

            //  Create the pipe if it does not exist yet.
            if (m_pipe == null && !IsTerminating)
            {
                ZObject[] parents = { this, m_socket };
                int[] hwms = { m_options.ReceiveHighWatermark, m_options.SendHighWatermark };
                bool[] delays = { m_options.DelayOnClose, m_options.DelayOnDisconnect };
                Pipe[] pipes = Pipe.PipePair(parents, hwms, delays);

                //  Plug the local end of the pipe.
                pipes[0].SetEventSink(this);

                //  Remember the local end of the pipe.
                Debug.Assert(m_pipe == null);
                m_pipe = pipes[0];

                //  Ask socket to plug into the remote end of the pipe.
                SendBind(m_socket, pipes[1]);
            }

            //  Plug in the engine.
            Debug.Assert(m_engine == null);
            m_engine = engine;
            m_engine.Plug(m_ioThread, this);
        }
Beispiel #34
0
 protected override void XTerminated(Pipe pipe)
 {
     if (pipe == m_pipe)
         m_pipe = null;
 }
Beispiel #35
0
        private void Detached()
        {
            //  Transient session self-destructs after peer disconnects.
            if (!m_connect)
            {
                Terminate();
                return;
            }

            //  For delayed connect situations, terminate the pipe
            //  and reestablish later on
            if (m_pipe != null && m_options.DelayAttachOnConnect
                    && m_addr.Protocol != Address.PgmProtocol && m_addr.Protocol != Address.EpgmProtocol)
            {
                m_pipe.Hiccup();
                m_pipe.Terminate(false);
                m_terminatingPipes.Add(m_pipe);
                m_pipe = null;
            }

            Reset();

            //  Reconnect.
            if (m_options.ReconnectIvl != -1)
                StartConnecting(true);

            //  For subscriber sockets we hiccup the inbound pipe, which will cause
            //  the socket object to resend all the subscriptions.
            if (m_pipe != null && (m_options.SocketType == ZmqSocketType.Sub || m_options.SocketType == ZmqSocketType.Xsub))
                m_pipe.Hiccup();
        }
Beispiel #36
0
 protected override void XReadActivated(Pipe pipe)
 {
     //  There's just one pipe. No lists of active and inactive pipes.
     //  There's nothing to do here.
 }
Beispiel #37
0
 public void Hiccuped(Pipe pipe)
 {
     //  Hiccups are always sent from session to socket, not the other
     //  way round.
     throw new NotSupportedException("Must Override");
 }