Пример #1
0
 /// <summary>
 ///     Create a new IOObject object and plug it into the given IOThread.
 /// </summary>
 /// <param name="ioThread">the IOThread to plug this new IOObject into.</param>
 public IOObject([CanBeNull] IOThread ioThread)
 {
     if (ioThread != null)
     {
         this.Plug(ioThread);
     }
 }
Пример #2
0
        public IOThread ChooseIOThread(long affinity)
        {
            if (this.m_ioThreads.Count == 0)
            {
                return(null);
            }

            // Find the I/O thread with minimum load.
            int      minLoad          = -1;
            IOThread selectedIOThread = null;

            for (int i = 0; i != this.m_ioThreads.Count; i++)
            {
                IOThread ioThread = this.m_ioThreads[i];

                if (affinity == 0 || (affinity & (1L << i)) > 0)
                {
                    if (selectedIOThread == null || ioThread.Load < minLoad)
                    {
                        minLoad          = ioThread.Load;
                        selectedIOThread = ioThread;
                    }
                }
            }

            return(selectedIOThread);
        }
Пример #3
0
        /// <summary>
        ///     "Un-Plug" this IOObject from its current IOThread, and set its handler to null.
        /// </summary>
        /// <remarks>
        ///     When migrating an object from one I/O thread to another, first
        ///     unplug it, then migrate it, then plug it to the new thread.
        /// </remarks>
        public void Unplug()
        {
            Debug.Assert(this.m_ioThread != null);

            // Forget about old poller in preparation to be migrated
            // to a different I/O thread.
            this.m_ioThread = null;
            this.m_handler  = null;
        }
Пример #4
0
        /// <summary>
        ///     Create a new SessionBase object from the given IOThread, socket, and Address.
        /// </summary>
        /// <param name="ioThread">the IOThread for this session to run on</param>
        /// <param name="connect">this flag dictates whether to connect</param>
        /// <param name="socket">the socket to contain</param>
        /// <param name="options">Options that dictate the settings of this session</param>
        /// <param name="addr">an Address that dictates the protocol and IP-address to use when connecting</param>
        public SessionBase([NotNull] IOThread ioThread, bool connect, [NotNull] SocketBase socket, [NotNull] Options options, [NotNull] Address addr)
            : base(ioThread, options)
        {
            this.m_ioObject = new IOObject(ioThread);

            this.m_connect  = connect;
            this.m_socket   = socket;
            this.m_ioThread = ioThread;
            this.m_addr     = addr;

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

            this.m_terminatingPipes = new HashSet <Pipe>();
        }
Пример #5
0
        public static SessionBase Create([NotNull] IOThread ioThread, bool connect, [NotNull] SocketBase socket, [NotNull] Options options, [NotNull] Address addr)
        {
            switch (options.SocketType)
            {
            case ZmqSocketType.Req:
                return(new Req.ReqSession(ioThread, connect, socket, options, addr));

            case ZmqSocketType.Dealer:
                return(new Dealer.DealerSession(ioThread, connect, socket, options, addr));

            case ZmqSocketType.Rep:
                return(new Rep.RepSession(ioThread, connect, socket, options, addr));

            case ZmqSocketType.Router:
                return(new Router.RouterSession(ioThread, connect, socket, options, addr));

            case ZmqSocketType.Pub:
                return(new Pub.PubSession(ioThread, connect, socket, options, addr));

            case ZmqSocketType.Xpub:
                return(new XPub.XPubSession(ioThread, connect, socket, options, addr));

            case ZmqSocketType.Sub:
                return(new Sub.SubSession(ioThread, connect, socket, options, addr));

            case ZmqSocketType.Xsub:
                return(new XSub.XSubSession(ioThread, connect, socket, options, addr));

            case ZmqSocketType.Push:
                return(new Push.PushSession(ioThread, connect, socket, options, addr));

            case ZmqSocketType.Pull:
                return(new Pull.PullSession(ioThread, connect, socket, options, addr));

            case ZmqSocketType.Pair:
                return(new Pair.PairSession(ioThread, connect, socket, options, addr));

            case ZmqSocketType.Stream:
                return(new Stream.StreamSession(ioThread, connect, socket, options, addr));

            default:
                throw new InvalidException("SessionBase.Create called with invalid SocketType of " + options.SocketType);
            }
        }
Пример #6
0
        /// <summary>
        ///     Begin connecting.
        /// </summary>
        /// <param name="wait">Whether to wait a bit before actually attempting to connect</param>
        private void StartConnecting(bool wait)
        {
            Debug.Assert(this.m_connect);

            // Choose I/O thread to run connector in. Given that we are already
            // running in an I/O thread, there must be at least one available.
            IOThread ioThread = this.ChooseIOThread(this.m_options.Affinity);

            Debug.Assert(ioThread != null);

            // Create the connector object.

            switch (this.m_addr.Protocol)
            {
            case Address.TcpProtocol:
            {
                this.LaunchChild(new TcpConnector(ioThread, this, this.m_options, this.m_addr, wait));
                return;
            }

            case Address.IpcProtocol:
            {
                this.LaunchChild(new IpcConnector(ioThread, this, this.m_options, this.m_addr, wait));
                return;
            }

            case Address.PgmProtocol:
            case Address.EpgmProtocol:
            {
                PgmSender pgmSender = new PgmSender(this.m_ioThread, this.m_options, this.m_addr, wait);
                pgmSender.Init((PgmAddress)this.m_addr.Resolved);
                this.SendAttach(this, pgmSender);
                return;
            }
            }

            Debug.Assert(false);
        }
Пример #7
0
        public SocketBase CreateSocket(ZmqSocketType type)
        {
            lock (this.m_slotSync)
            {
                if (this.m_starting)
                {
                    this.m_starting = false;
                    // Initialise the array of mailboxes. Additional three slots are for
                    // zmq_term thread and reaper thread.

                    int ios;
                    int mazmq;

                    lock (this.m_optSync)
                    {
                        mazmq = this.m_maxSockets;
                        ios   = this.m_ioThreadCount;
                    }

                    this.m_slotCount = mazmq + ios + 2;
                    this.m_slots     = new IMailbox[this.m_slotCount];
                    //alloc_Debug.Assert(slots);

                    // Initialise the infrastructure for zmq_term thread.
                    this.m_slots[Ctx.TermTid] = this.m_termMailbox;

                    // Create the reaper thread.
                    this.m_reaper = new Reaper(this, Ctx.ReaperTid);
                    //alloc_Debug.Assert(reaper);
                    this.m_slots[Ctx.ReaperTid] = this.m_reaper.Mailbox;
                    this.m_reaper.Start();

                    // Create I/O thread objects and launch them.
                    for (int i = 2; i != ios + 2; i++)
                    {
                        IOThread ioThread = new IOThread(this, i);
                        //alloc_Debug.Assert(io_thread);
                        this.m_ioThreads.Add(ioThread);
                        this.m_slots[i] = ioThread.Mailbox;
                        ioThread.Start();
                    }

                    // In the unused part of the slot array, create a list of empty slots.
                    for (int i = this.m_slotCount - 1; i >= ios + 2; i--)
                    {
                        this.m_emptySlots.Push(i);
                        this.m_slots[i] = null;
                    }
                }

                // Once zmq_term() was called, we can't create new sockets.
                if (this.m_terminating)
                {
                    string xMsg = $"Ctx.CreateSocket({type}), cannot create new socket while terminating.";
                    throw new TerminatingException(null, xMsg);
                }

                // If max_sockets limit was reached, return error.
                if (this.m_emptySlots.Count == 0)
                {
                    #if DEBUG
                    string xMsg = $"Ctx.CreateSocket({type}), max number of sockets {this.m_maxSockets} reached.";
                    throw NetMQException.Create(xMsg, ErrorCode.TooManyOpenSockets);
                    #else
                    throw NetMQException.Create(ErrorCode.TooManyOpenSockets);
                                        #endif
                }

                // Choose a slot for the socket.
                int slot = this.m_emptySlots.Pop();

                // Generate new unique socket ID.
                int socketId = Interlocked.Increment(ref Ctx.s_maxSocketId);

                // Create the socket and register its mailbox.
                SocketBase s = SocketBase.Create(type, this, slot, socketId);

                this.m_sockets.Add(s);
                this.m_slots[slot] = s.Mailbox;

                //LOG.debug("NEW Slot [" + slot + "] " + s);

                return(s);
            }
        }
Пример #8
0
 /// <summary>
 ///     Initializes a new instance of the <see cref="Own" /> class that is running within I/O thread.
 /// </summary>
 /// <param name="ioThread">The I/O thread.</param>
 /// <param name="options">The options.</param>
 /// <remarks>
 ///     Note that the owner is unspecified in the constructor. It'll be assigned later on using <see cref="SetOwner" />
 ///     when the object is plugged in.
 /// </remarks>
 protected Own([NotNull] IOThread ioThread, [NotNull] Options options)
     : base(ioThread)
 {
     this.m_options = options;
 }
Пример #9
0
        /// <summary>
        ///     "Plug in" this IOObject to the given IOThread, - ie associate this with the specified IOThread.
        /// </summary>
        /// <param name="ioThread">the IOThread for this object to live in</param>
        /// <remarks>
        ///     When migrating an object from one I/O thread to another, first
        ///     unplug it, then migrate it, then plug it to the new thread.
        /// </remarks>
        public void Plug([NotNull] IOThread ioThread)
        {
            Debug.Assert(ioThread != null);

            this.m_ioThread = ioThread;
        }