void zmq::zmq_connecter_t::out_event () { fd_t fd = tcp_connecter.connect (); rm_fd (handle); handle_valid = false; // Handle the error condition by attempt to reconnect. if (fd == retired_fd) { tcp_connecter.close (); wait = true; add_reconnect_timer(); return; } // Choose I/O thread to run connecter in. Given that we are already // running in an I/O thread, there must be at least one available. io_thread_t *io_thread = choose_io_thread (options.affinity); zmq_assert (io_thread); // Create an init object. zmq_init_t *init = new (std::nothrow) zmq_init_t (io_thread, NULL, session, fd, options); alloc_assert (init); launch_sibling (init); // Shut the connecter down. terminate (); }
void zmq::zmq_listener_t::in_event () { fd_t fd = tcp_listener.accept (); // If connection was reset by the peer in the meantime, just ignore it. // TODO: Handle specific errors like ENFILE/EMFILE etc. if (fd == retired_fd) return; // Choose I/O thread to run connecter in. Given that we are already // running in an I/O thread, there must be at least one available. io_thread_t *io_thread = choose_io_thread (options.affinity); zmq_assert (io_thread); // Create and launch an init object. zmq_init_t *init = new (std::nothrow) zmq_init_t (io_thread, socket, NULL, fd, options); zmq_assert (init); launch_sibling (init); }
void zmq::zmq_init_t::dispatch_engine () { if (to_send.empty () && received) { // Engine must be detached. zmq_assert (!engine); zmq_assert (ephemeral_engine); // If we know what session we belong to, it's easy, just send the // engine to that session and destroy the init object. Note that we // know about the session only if this object is owned by it. Thus, // lifetime of this object in contained in the lifetime of the session // so the pointer cannot become invalid without notice. if (session) { send_attach (session, ephemeral_engine, peer_identity, true); terminate (); return; } // All the cases below are listener-based. Therefore we need the socket // reference so that new sessions can bind to that socket. zmq_assert (socket); // We have no associated session. If the peer has no identity we'll // create a transient session for the connection. Note that // seqnum is incremented to account for attach command before the // session is launched. That way we are sure it won't terminate before // being attached. if (peer_identity [0] == 0) { session = new (std::nothrow) transient_session_t (io_thread, socket, options); alloc_assert (session); session->inc_seqnum (); launch_sibling (session); send_attach (session, ephemeral_engine, peer_identity, false); terminate (); return; } // Try to find the session corresponding to the peer's identity. // If found, send the engine to that session and destroy this object. // Note that session's seqnum is incremented by find_session rather // than by send_attach. session = socket->find_session (peer_identity); if (session) { send_attach (session, ephemeral_engine, peer_identity, false); terminate (); return; } // There's no such named session. We have to create one. Note that // seqnum is incremented to account for attach command before the // session is launched. That way we are sure it won't terminate before // being attached. session = new (std::nothrow) named_session_t (io_thread, socket, options, peer_identity); alloc_assert (session); session->inc_seqnum (); launch_sibling (session); send_attach (session, ephemeral_engine, peer_identity, false); terminate (); return; } }