コード例 #1
0
ファイル: Pipe.cs プロジェクト: somdoron/NetMQ4
        internal Pipe(Socket parent, YPipe<Frame> inpipe, YPipe<Frame> outpipe,
            int inHighWatermark, int outHighWatermark)
            : base(parent)
        {
            m_inpipe = inpipe;
            m_outpipe = outpipe;

            m_inActive = true;
            m_outActive = true;

            m_highWatermark = outHighWatermark;
            ComputeLowWatermark(inHighWatermark);

            m_delay = true;
            m_state = State.Active;
        }
コード例 #2
0
ファイル: Mailbox.cs プロジェクト: EugenDueck/netmq
        public Mailbox(String name)
        {
            m_cpipe = new YPipe<Command>(Config.CommandPipeGranularity, "mailbox");
            m_sync = new object();
            m_signaler = new Signaler();

            //  Get the pipe into passive state. That way, if the users starts by
            //  polling on the associated file descriptor it will get woken up when
            //  new command is posted.

            Command cmd = m_cpipe.Read();
            Debug.Assert(cmd == null);
            m_active = false;

            m_name = name;
        }
コード例 #3
0
ファイル: Pipe.cs プロジェクト: ezhuo/netmq
        //  Constructor is private. Pipe can only be created using
        //  pipepair function.
        private Pipe(ZObject parent, YPipe<Msg> inpipe, YPipe<Msg> outpipe,
		              int inhwm, int outhwm, bool delay)
            : base(parent)
        {
            m_parent = parent;
            m_inpipe = inpipe;
            m_outpipe = outpipe;
            m_inActive = true;
            m_outActive = true;
            m_hwm = outhwm;
            m_lwm = ComputeLwm (inhwm);
            m_msgsRead = 0;
            m_msgsWritten = 0;
            m_peersMsgsRead = 0;
            m_peer = null ;
            m_sink = null ;
            m_state = State.Active;
            m_delay = delay;
        }
コード例 #4
0
ファイル: Pipe.cs プロジェクト: EugenDueck/netmq
 ///<remarks> Constructor is private as pipe can only be created using <see cref="PipePair"/> method. </remarks>
 private Pipe(ZObject parent, YPipe<Msg> inboundPipe, YPipe<Msg> outboundPipe,
               int inHighWatermark, int outHighWatermark, bool delay)
     : base(parent)
 {
     m_parent = parent;
     m_inboundPipe = inboundPipe;
     m_outboundPipe = outboundPipe;
     m_inActive = true;
     m_outActive = true;
     m_highWatermark = outHighWatermark;
     m_lowWatermark = ComputeLowWatermark(inHighWatermark);
     m_numberOfMessagesRead = 0;
     m_numberOfMessagesWritten = 0;
     m_peersMsgsRead = 0;
     m_peer = null;
     m_sink = null;
     m_state = State.Active;
     m_delay = delay;
 }
コード例 #5
0
ファイル: Pipe.cs プロジェクト: somdoron/NetMQ4
        /// <summary>
        /// Temporarily disconnects the inbound message stream and drops
        /// all the messages on the fly. Causes 'hiccuped' event to be generated
        /// in the peer.
        /// </summary>
        public void Hiccup()
        {
            // If dispose is already under way do nothing.
            if (m_state == State.Active)
            {
                //  We'll drop the reference to the inpipe. From now on, the peer is
                //  responsible for deallocating it.
                m_inpipe = null;

                //  Create new inpipe.
                m_inpipe = new YPipe<Frame>();
                m_inActive = true;

                //  Notify the peer about the hiccup.
                CommandDispatcher.SendHiccup(m_peer, m_inpipe);
            }
        }
コード例 #6
0
ファイル: Pipe.cs プロジェクト: vordoom/netmq
        /// <summary>
        /// Temporarily disconnects the inbound message stream and drops
        /// all the messages on the fly. Causes 'hiccuped' event to be generated in the peer.
        /// </summary>
        public void Hiccup()
        {
            // If termination is already under way do nothing.
            if (m_state != State.Active)
                return;

            // We'll drop the pointer to the in-pipe. From now on, the peer is
            // responsible for deallocating it.
            m_inboundPipe = null;

            // Create new in-pipe.
            m_inboundPipe = new YPipe<Msg>(Config.MessagePipeGranularity, "inpipe");
            m_inActive = true;

            // Notify the peer about the hiccup.
            SendHiccup(m_peer, m_inboundPipe);
        }
コード例 #7
0
ファイル: Pipe.cs プロジェクト: vordoom/netmq
        /// <summary>
        /// Handles the delimiter read from the pipe.
        /// </summary>
        private void Delimit()
        {
            if (m_state == State.Active)
            {
                m_state = State.Delimited;
                return;
            }

            if (m_state == State.Pending)
            {
                m_outboundPipe = null;
                SendPipeTermAck(m_peer);
                m_state = State.Terminating;
                return;
            }

            // Delimiter in any other state is invalid.
            Debug.Assert(false);
        }
コード例 #8
0
ファイル: Pipe.cs プロジェクト: vordoom/netmq
        /// <summary>
        /// Ask pipe to terminate. The termination will happen asynchronously
        /// and user will be notified about actual deallocation by 'terminated'
        /// event.
        /// </summary>
        /// <param name="delay">if set to <c>true</c>, the pending messages will be processed
        /// before actual shutdown. </param>
        public void Terminate(bool delay)
        {
            // Overload the value specified at pipe creation.
            m_delay = delay;

            // If terminate was already called, we can ignore the duplicate invocation.
            if (m_state == State.Terminated || m_state == State.DoubleTerminated)
                return;

            // If the pipe is in the phase of async termination, it's going to
            // closed anyway. No need to do anything special here.
            if (m_state == State.Terminating)
                return;

            if (m_state == State.Active)
            {
                // The simple sync termination case. Ask the peer to terminate and wait
                // for the ack.
                SendPipeTerm(m_peer);
                m_state = State.Terminated;
            }
            else if (m_state == State.Pending && !m_delay)
            {
                // There are still pending messages available, but the user calls
                // 'terminate'. We can act as if all the pending messages were read.
                m_outboundPipe = null;
                SendPipeTermAck(m_peer);
                m_state = State.Terminating;
            }
            else if (m_state == State.Pending)
            {
                // If there are pending messages still available, do nothing.
            }
            else if (m_state == State.Delimited)
            {
                // We've already got delimiter, but not term command yet. We can ignore
                // the delimiter and ack synchronously terminate as if we were in
                // active state.
                SendPipeTerm(m_peer);
                m_state = State.Terminated;
            }
            else
            {
                // There are no other states.
                Debug.Assert(false);
            }

            // Stop outbound flow of messages.
            m_outActive = false;

            if (m_outboundPipe != null)
            {
                // Drop any unfinished outbound messages.
                Rollback();

                // Write the delimiter into the pipe. Note that watermarks are not
                // checked; thus the delimiter can be written even when the pipe is full.

                var msg = new Msg();
                msg.InitDelimiter();
                m_outboundPipe.Write(ref msg, false);
                Flush();
            }
        }
コード例 #9
0
ファイル: Pipe.cs プロジェクト: vordoom/netmq
        /// <summary>
        /// Process the pipe-termination ack.
        /// </summary>
        protected override void ProcessPipeTermAck()
        {
            // Notify the user that all the references to the pipe should be dropped.
            Debug.Assert(m_sink != null);
            m_sink.Terminated(this);

            // In terminating and double_terminated states there's nothing to do.
            // Simply deallocate the pipe. In terminated state we have to ack the
            // peer before deallocating this side of the pipe. All the other states
            // are invalid.
            if (m_state == State.Terminated)
            {
                m_outboundPipe = null;
                SendPipeTermAck(m_peer);
            }
            else
                Debug.Assert(m_state == State.Terminating || m_state == State.DoubleTerminated);

            // We'll deallocate the inbound pipe, the peer will deallocate the outbound
            // pipe (which is an inbound pipe from its point of view).
            // First, delete all the unread messages in the pipe. We have to do it by
            // hand because msg_t doesn't have automatic destructor. Then deallocate
            // the ypipe itself.
            var msg = new Msg();
            while (m_inboundPipe.TryRead(out msg))
            {
                msg.Close();
            }

            m_inboundPipe = null;
        }
コード例 #10
0
ファイル: Pipe.cs プロジェクト: vordoom/netmq
        protected override void ProcessPipeTerm()
        {
            // This is the simple case of peer-induced termination. If there are no
            // more pending messages to read, or if the pipe was configured to drop
            // pending messages, we can move directly to the terminating state.
            // Otherwise we'll hang up in pending state till all the pending messages
            // are sent.
            if (m_state == State.Active)
            {
                if (!m_delay)
                {
                    m_state = State.Terminating;
                    m_outboundPipe = null;
                    SendPipeTermAck(m_peer);
                }
                else
                    m_state = State.Pending;
                return;
            }

            // Delimiter happened to arrive before the term command. Now we have the
            // term command as well, so we can move straight to terminating state.
            if (m_state == State.Delimited)
            {
                m_state = State.Terminating;
                m_outboundPipe = null;
                SendPipeTermAck(m_peer);
                return;
            }

            // This is the case where both ends of the pipe are closed in parallel.
            // We simply reply to the request by ack and continue waiting for our
            // own ack.
            if (m_state == State.Terminated)
            {
                m_state = State.DoubleTerminated;
                m_outboundPipe = null;
                SendPipeTermAck(m_peer);
                return;
            }

            // pipe_term is invalid in other states.
            Debug.Assert(false);
        }
コード例 #11
0
ファイル: Pipe.cs プロジェクト: vordoom/netmq
        /// <summary>
        /// This method is called to assign the specified pipe as a replacement for the outbound pipe that was being used.
        /// </summary>
        /// <param name="pipe">the pipe to use for writing</param>
        /// <remarks>
        /// A "Hiccup" occurs when an outbound pipe experiences something like a transient disconnect or for whatever other reason
        /// is no longer available for writing to.
        /// </remarks>
        protected override void ProcessHiccup(object pipe)
        {
            // Destroy old out-pipe. Note that the read end of the pipe was already
            // migrated to this thread.
            Debug.Assert(m_outboundPipe != null);
            m_outboundPipe.Flush();
            var msg = new Msg();
            while (m_outboundPipe.TryRead(out msg))
            {
                msg.Close();
            }

            // Plug in the new out-pipe.
            Debug.Assert(pipe != null);
            m_outboundPipe = (YPipe<Msg>)pipe;
            m_outActive = true;

            // If appropriate, notify the user about the hiccup.
            if (m_state == State.Active)
                m_sink.Hiccuped(this);
        }
コード例 #12
0
ファイル: Pipe.cs プロジェクト: vordoom/netmq
        public static Pipe[] PipePair([NotNull] ZObject[] parents, [NotNull] int[] highWaterMarks, [NotNull] int[] lowWaterMarks, [NotNull] bool[] delays)
        {
            // Creates two pipe objects. These objects are connected by two ypipes,
            // each to pass messages in one direction.

            var upipe1 = new YPipe<Msg>(Config.MessagePipeGranularity, "upipe1");
            var upipe2 = new YPipe<Msg>(Config.MessagePipeGranularity, "upipe2");

            var pipes = new[]
            {
                new Pipe(parents[0], upipe1, upipe2, highWaterMarks[1], highWaterMarks[0], lowWaterMarks[1], delays[0]),
                new Pipe(parents[1], upipe2, upipe1, highWaterMarks[0], highWaterMarks[1], lowWaterMarks[0], delays[1])
            };

            pipes[0].SetPeer(pipes[1]);
            pipes[1].SetPeer(pipes[0]);

            return pipes;
        }
コード例 #13
0
ファイル: Pipe.cs プロジェクト: somdoron/NetMQ4
        internal override void Process(HiccupCommand command)
        {
            //  Destroy old outpipe. Note that the read end of the pipe was already
            //  migrated to this thread.
            m_outpipe.Flush();

            Frame frame;

            // empty the outpipe
            while (m_outpipe.TryRead(out frame))
            {
                if (!frame.More)
                    m_messagesWritten--;

                frame.Close();
            }

            //  Plug in the new outpipe.
            m_outpipe = command.Pipe;
            m_outActive = true;

            //  If appropriate, notify the user about the hiccup.
            if (m_state == State.Active)
            {
                var temp = Hiccuped;
                if (temp != null)
                {
                    temp(this, new PipeEventArgs(this));
                }
            }
        }
コード例 #14
0
ファイル: Pipe.cs プロジェクト: ezhuo/netmq
        //  Create a pipepair for bi-directional transfer of messages.
        //  First HWM is for messages passed from first pipe to the second pipe.
        //  Second HWM is for messages passed from second pipe to the first pipe.
        //  Delay specifies how the pipe behaves when the peer terminates. If true
        //  pipe receives all the pending messages before terminating, otherwise it
        //  terminates straight away.
        public static void Pipepair(ZObject[] parents, Pipe[] pipes, int[] hwms,
		                            bool[] delays)
        {
            //   Creates two pipe objects. These objects are connected by two ypipes,
            //   each to pass messages in one direction.

            YPipe<Msg> upipe1 = new YPipe<Msg>(Config.MessagePipeGranularity, "upipe1");
            YPipe<Msg> upipe2 = new YPipe<Msg>(Config.MessagePipeGranularity, "upipe2");

            pipes [0] = new Pipe(parents [0], upipe1, upipe2,
                                  hwms [1], hwms [0], delays [0]);
            pipes [1] = new Pipe(parents [1], upipe2, upipe1,
                                  hwms [0], hwms [1], delays [1]);

            pipes [0].SetPeer (pipes [1]);
            pipes [1].SetPeer (pipes [0]);
        }
コード例 #15
0
ファイル: CommandDispatcher.cs プロジェクト: somdoron/NetMQ4
 public static void SendHiccup(Pipe destination, YPipe<Frame> pipe)
 {
     var command = new HiccupCommand(destination, pipe);
     SendCommand(command);
 }
コード例 #16
0
ファイル: Command.cs プロジェクト: somdoron/NetMQ4
 public HiccupCommand(BaseObject destination, YPipe<Frame> pipe)
     : base(destination)
 {
     Pipe = pipe;
 }
コード例 #17
0
ファイル: Pipe.cs プロジェクト: somdoron/NetMQ4
        public static void CreatePair(Socket connectSocket, Socket bindSocket,
            int connetHighWatermark, int bindHighwatermark, out Pipe connectPipe, out Pipe bindPipe)
        {
            //   Creates two pipe objects. These objects are connected by two ypipes,
            //   each to pass messages in one direction.

            YPipe<Frame> upipe1 = new YPipe<Frame>();
            YPipe<Frame> upipe2 = new YPipe<Frame>();

            connectPipe = new Pipe(connectSocket, upipe1, upipe2, connetHighWatermark, bindHighwatermark);
            bindPipe = new Pipe(bindSocket, upipe2, upipe1, bindHighwatermark, connetHighWatermark);

            connectPipe.SetPeer(bindPipe);
            bindPipe.SetPeer(connectPipe);
        }
コード例 #18
0
ファイル: Pipe.cs プロジェクト: somdoron/NetMQ4
        private void CompleteClose()
        {
            m_outpipe = null;
            m_state = State.Closed;

            //  We'll deallocate the inbound pipe, the peer will deallocate the outbound
            //  pipe (which is an inbound pipe from its point of view).
            //  Delete all the unread messages in the pipe. We have to do it by
            //  hand because Frame need to release buffer pool memory.
            Frame frame;
            while (m_inpipe.TryRead(out frame))
            {
                frame.Close();
            }

            //  Notify the user that all the references to the pipe should be dropped.
            var temp = PipeClosed;
            if (temp != null)
            {
                temp(this, new PipeEventArgs(this));
            }
        }