/// <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) { Plug(ioThread); } }
/// <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(IOThread ioThread) { if (ioThread != null) { Plug(ioThread); } }
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: case ZmqSocketType.Rep: case ZmqSocketType.Router: case ZmqSocketType.Pub: case ZmqSocketType.Xpub: case ZmqSocketType.Sub: case ZmqSocketType.Xsub: case ZmqSocketType.Push: case ZmqSocketType.Pull: case ZmqSocketType.Pair: case ZmqSocketType.Stream: case ZmqSocketType.Peer: if (options.CanSendHelloMsg && options.HelloMsg != null) { return(new HelloMsgSession(ioThread, connect, socket, options, addr)); } else { return(new SessionBase(ioThread, connect, socket, options, addr)); } default: throw new InvalidException("SessionBase.Create called with invalid SocketType of " + options.SocketType); } }
public IOThread ChooseIOThread(long affinity) { if (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 != m_ioThreads.Count; i++) { var ioThread = 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(m_ioThread != null); // Forget about old poller in preparation to be migrated // to a different I/O thread. m_ioThread = null; 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(IOThread ioThread, bool connect, SocketBase socket, Options options, Address addr) : base(ioThread, options) { m_ioObject = new IOObject(ioThread); m_connect = connect; m_socket = socket; m_ioThread = ioThread; m_addr = addr; 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)); case ZmqSocketType.Peer: return(new Peer.PeerSession(ioThread, connect, socket, options, addr)); default: throw new InvalidException("SessionBase.Create called with invalid SocketType of " + options.SocketType); } }
/// <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(IOThread ioThread, bool connect, SocketBase socket, Options options, Address addr) : base(ioThread, options) { m_ioObject = new IOObject(ioThread); m_connect = connect; m_socket = socket; m_ioThread = ioThread; m_addr = addr; if (options.RawSocket) { m_identitySent = true; m_identityReceived = true; } m_terminatingPipes = new HashSet <Pipe>(); }
/// <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(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 = ChooseIOThread(m_options.Affinity); Debug.Assert(ioThread != null); // Create the connector object. switch (m_addr.Protocol) { case Address.TcpProtocol: { LaunchChild(new TcpConnector(ioThread, this, m_options, m_addr, wait)); return; } case Address.IpcProtocol: { LaunchChild(new IpcConnector(ioThread, this, m_options, m_addr, wait)); return; } case Address.PgmProtocol: case Address.EpgmProtocol: { var pgmSender = new PgmSender(m_ioThread, m_options, m_addr, wait); pgmSender.Init((PgmAddress)m_addr.Resolved); SendAttach(this, pgmSender); return; } } Debug.Assert(false); }
/// <summary> /// Create a return a new session. /// The specific subclass of SessionBase that is created is dictated by the SocketType specified by the options argument. /// </summary> /// <param name="ioThread">the <c>IOThread</c> for this session to run in</param> /// <param name="connect">whether to immediately connect</param> /// <param name="socket">the socket to connect</param> /// <param name="options">an <c>Options</c> that provides the SocketType that dictates which type of session to create</param> /// <param name="addr">an <c>Address</c> object that specifies the protocol and address to connect to</param> /// <returns>the newly-created instance of whichever subclass of SessionBase is specified by the options</returns> /// <exception cref="InvalidException">The socket must be of the correct type.</exception> public static SessionBase Create( IOThread ioThread, bool connect, SocketBase socket, Options options, 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> /// "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(IOThread ioThread) { Debug.Assert(ioThread != null); m_ioThread = ioThread; }
/// <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) { m_ioObject = new IOObject(ioThread); m_connect = connect; m_socket = socket; m_ioThread = ioThread; m_addr = addr; if (options.RawSocket) { m_identitySent = true; m_identityReceived = true; } m_terminatingPipes = new HashSet<Pipe>(); }
/// <summary> /// Create and return a new socket of the given type, and initialize this Ctx if this is the first one. /// </summary> /// <param name="type">the type of socket to create</param> /// <returns>the newly-created socket</returns> /// <exception cref="TerminatingException">Cannot create new socket while terminating.</exception> /// <exception cref="NetMQException">Maximum number of sockets reached.</exception> /// <exception cref="TerminatingException">The context (Ctx) must not be already terminating.</exception> public SocketBase CreateSocket(ZmqSocketType type) { lock (m_slotSync) { if (m_starting) { m_starting = false; // Initialise the array of mailboxes. Additional three slots are for // zmq_term thread and reaper thread. int ios; int mazmq; lock (m_optSync) { mazmq = m_maxSockets; ios = m_ioThreadCount; } m_slotCount = mazmq + ios + 2; m_slots = new IMailbox[m_slotCount]; //alloc_Debug.Assert(slots); // Initialise the infrastructure for zmq_term thread. m_slots[TermTid] = m_termMailbox; // Create the reaper thread. m_reaper = new Reaper(this, ReaperTid); //alloc_Debug.Assert(reaper); m_slots[ReaperTid] = m_reaper.Mailbox; m_reaper.Start(); // Create I/O thread objects and launch them. for (int i = 2; i != ios + 2; i++) { var ioThread = new IOThread(this, i); //alloc_Debug.Assert(io_thread); m_ioThreads.Add(ioThread); m_slots[i] = ioThread.Mailbox; ioThread.Start(); } // In the unused part of the slot array, create a list of empty slots. for (int i = m_slotCount - 1; i >= ios + 2; i--) { m_emptySlots.Push(i); m_slots[i] = null; } } // Once zmq_term() was called, we can't create new sockets. if (m_terminating) { string xMsg = string.Format("Ctx.CreateSocket({0}), cannot create new socket while terminating.", type); throw new TerminatingException(innerException: null, message: xMsg); } // If max_sockets limit was reached, return error. if (m_emptySlots.Count == 0) { #if DEBUG string xMsg = string.Format("Ctx.CreateSocket({0}), max number of sockets {1} reached.", type, m_maxSockets); throw NetMQException.Create(xMsg, ErrorCode.TooManyOpenSockets); #else throw NetMQException.Create(ErrorCode.TooManyOpenSockets); #endif } // Choose a slot for the socket. int slot = m_emptySlots.Pop(); // Generate new unique socket ID. int socketId = Interlocked.Increment(ref s_maxSocketId); // Create the socket and register its mailbox. SocketBase s = SocketBase.Create(type, this, slot, socketId); m_sockets.Add(s); m_slots[slot] = s.Mailbox; //LOG.debug("NEW Slot [" + slot + "] " + s); return s; } }
/// <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( IOThread ioThread) { if (ioThread != null) Plug(ioThread); }
/// <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); m_ioThread = ioThread; }
/// <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(IOThread ioThread, Options options) : base(ioThread) { m_options = options; }
/// <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( IOThread ioThread, Options options) : base(ioThread) { m_options = options; }
public SocketBase CreateSocket(ZmqSocketType type) { lock (m_slotSync) { if (m_starting) { m_starting = false; // Initialise the array of mailboxes. Additional three slots are for // zmq_term thread and reaper thread. int ios; int mazmq; lock (m_optSync) { mazmq = m_maxSockets; ios = m_ioThreadCount; } m_slotCount = mazmq + ios + 2; m_slots = new IMailbox[m_slotCount]; //alloc_Debug.Assert(slots); // Initialise the infrastructure for zmq_term thread. m_slots[TermTid] = m_termMailbox; // Create the reaper thread. m_reaper = new Reaper(this, ReaperTid); //alloc_Debug.Assert(reaper); m_slots[ReaperTid] = m_reaper.Mailbox; m_reaper.Start(); // Create I/O thread objects and launch them. for (int i = 2; i != ios + 2; i++) { var ioThread = new IOThread(this, i); //alloc_Debug.Assert(io_thread); m_ioThreads.Add(ioThread); m_slots[i] = ioThread.Mailbox; ioThread.Start(); } // In the unused part of the slot array, create a list of empty slots. for (int i = m_slotCount - 1; i >= ios + 2; i--) { m_emptySlots.Push(i); m_slots[i] = null; } } // Once zmq_term() was called, we can't create new sockets. if (m_terminating) { string xMsg = string.Format("Ctx.CreateSocket({0}), cannot create new socket while terminating.", type); throw new TerminatingException(innerException: null, message: xMsg); } // If max_sockets limit was reached, return error. if (m_emptySlots.Count == 0) { #if DEBUG string xMsg = string.Format("Ctx.CreateSocket({0}), max number of sockets {1} reached.", type, m_maxSockets); throw NetMQException.Create(xMsg, ErrorCode.TooManyOpenSockets); #else throw NetMQException.Create(ErrorCode.TooManyOpenSockets); #endif } // Choose a slot for the socket. int slot = m_emptySlots.Pop(); // Generate new unique socket ID. int socketId = Interlocked.Increment(ref s_maxSocketId); // Create the socket and register its mailbox. SocketBase s = SocketBase.Create(type, this, slot, socketId); m_sockets.Add(s); 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) { m_options = options; }
private static void Activate() { s_active = true; // Create I/O thread object and launch it s_ioThread = new IOThread(0); s_slots[0] = s_ioThread.Mailbox; s_ioThread.Start(); }
private static void Deactivate() { s_active = false; s_ioThread.Dispose(); s_ioThread = null; }
public HelloMsgSession([NotNull] IOThread ioThread, bool connect, [NotNull] SocketBase socket, [NotNull] Options options, [NotNull] Address addr) : base(ioThread, connect, socket, options, addr) { m_newPipe = true; }