/// <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); } }
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); }
/// <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; }
/// <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>(); }
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); } }
/// <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); }
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); } }
/// <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; }
/// <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; }