void zmq::stream_t::identify_peer (pipe_t *pipe_) { // Always assign identity for raw-socket unsigned char buffer [5]; buffer [0] = 0; blob_t identity; if (connect_rid.length ()) { identity = blob_t ((unsigned char*) connect_rid.c_str(), connect_rid.length ()); connect_rid.clear (); outpipes_t::iterator it = outpipes.find (identity); zmq_assert (it == outpipes.end ()); } else { put_uint32 (buffer + 1, next_rid++); identity = blob_t (buffer, sizeof buffer); memcpy (options.identity, identity.data (), identity.size ()); options.identity_size = (unsigned char) identity.size (); } pipe_->set_identity (identity); // Add the record into output pipes lookup table outpipe_t outpipe = {pipe_, true}; const bool ok = outpipes.insert ( outpipes_t::value_type (identity, outpipe)).second; zmq_assert (ok); }
void zmq::xpub_t::xread_activated (pipe_t *pipe_) { // There are some subscriptions waiting. Let's process them. msg_t sub; while (pipe_->read (&sub)) { // Apply the subscription to the trie. unsigned char *const data = (unsigned char*) sub.data (); const size_t size = sub.size (); if (size > 0 && (*data == 0 || *data == 1)) { bool unique; if (*data == 0) unique = subscriptions.rm (data + 1, size - 1, pipe_); else unique = subscriptions.add (data + 1, size - 1, pipe_); // If the subscription is not a duplicate store it so that it can be // passed to used on next recv call. (Unsubscribe is not verbose.) if (options.type == ZMQ_XPUB && (unique || (*data && verbose))) pending.push_back (blob_t (data, size)); } else // Process user message coming upstream from xsub socket pending.push_back (blob_t (data, size)); sub.close (); } }
void zmq::xpub_t::xread_activated (pipe_t *pipe_) { // There are some subscriptions waiting. Let's process them. msg_t sub; while (pipe_->read (&sub)) { // Apply the subscription to the trie unsigned char *const data = (unsigned char *) sub.data (); const size_t size = sub.size (); metadata_t *metadata = sub.metadata (); if (size > 0 && (*data == 0 || *data == 1)) { if (manual) { // Store manual subscription to use on termination if (*data == 0) manual_subscriptions.rm (data + 1, size - 1, pipe_); else manual_subscriptions.add (data + 1, size - 1, pipe_); pending_pipes.push_back (pipe_); pending_data.push_back (blob_t (data, size)); if (metadata) metadata->add_ref (); pending_metadata.push_back (metadata); pending_flags.push_back (0); } else { bool notify; if (*data == 0) { mtrie_t::rm_result rm_result = subscriptions.rm (data + 1, size - 1, pipe_); // TODO reconsider what to do if rm_result == mtrie_t::not_found notify = rm_result != mtrie_t::values_remain || verbose_unsubs; } else { bool first_added = subscriptions.add (data + 1, size - 1, pipe_); notify = first_added || verbose_subs; } // If the request was a new subscription, or the subscription // was removed, or verbose mode is enabled, store it so that // it can be passed to the user on next recv call. if (options.type == ZMQ_XPUB && notify) { pending_data.push_back (blob_t (data, size)); if (metadata) metadata->add_ref (); pending_metadata.push_back (metadata); pending_flags.push_back (0); } } } else { // Process user message coming upstream from xsub socket pending_data.push_back (blob_t (data, size)); if (metadata) metadata->add_ref (); pending_metadata.push_back (metadata); pending_flags.push_back (sub.flags ()); } sub.close (); } }
bool zmq::router_t::identify_peer (pipe_t *pipe_) { msg_t msg; blob_t identity; bool ok; if (options.raw_sock) { // Always assign identity for raw-socket unsigned char buf [5]; buf [0] = 0; put_uint32 (buf + 1, next_peer_id++); identity = blob_t (buf, sizeof buf); unsigned int i = 0; // Store identity to allow use of raw socket as client for (blob_t::iterator it = identity.begin(); it != identity.end(); it++) options.identity[i++] = *it; options.identity_size = i; } else { msg.init (); ok = pipe_->read (&msg); if (!ok) return false; if (msg.size () == 0) { // Fall back on the auto-generation unsigned char buf [5]; buf [0] = 0; put_uint32 (buf + 1, next_peer_id++); identity = blob_t (buf, sizeof buf); msg.close (); } else { identity = blob_t ((unsigned char*) msg.data (), msg.size ()); outpipes_t::iterator it = outpipes.find (identity); msg.close (); // Ignore peers with duplicate ID. if (it != outpipes.end ()) return false; } } pipe_->set_identity (identity); // Add the record into output pipes lookup table outpipe_t outpipe = {pipe_, true}; ok = outpipes.insert (outpipes_t::value_type (identity, outpipe)).second; zmq_assert (ok); return true; }
void zmq::mechanism_t::set_user_id (const void *data_, size_t size_) { user_id = blob_t (static_cast <const unsigned char*> (data_), size_); zap_properties.insert ( metadata_t::dict_t::value_type ( "User-Id", std::string ((char *) data_, size_))); }
int zmq::router_t::xgetsockopt (int option_, const void *optval_, size_t *optvallen_) { switch (option_) { case ZMQ_IDENTITY_FD: if (optval_==NULL && optvallen_) { *optvallen_=sizeof(fd_t); return 0; } if (optval_ && optvallen_ && *optvallen_) { blob_t identity= blob_t((unsigned char*)optval_,*optvallen_); outpipes_t::iterator it = outpipes.find (identity); if (it == outpipes.end() ){ return ENOTSOCK; } *((fd_t*)optval_)=it->second.pipe->assoc_fd; *optvallen_=sizeof(fd_t); return 0; } break; default: break; } errno = EINVAL; return -1; }
void zmq::xpub_t::xread_activated (pipe_t *pipe_) { // There are some subscriptions waiting. Let's process them. msg_t sub; while (pipe_->read (&sub)) { // Apply the subscription to the trie. unsigned char *const data = (unsigned char*) sub.data (); const size_t size = sub.size (); if (size > 0 && (*data == 0 || *data == 1)) { bool unique; if (*data == 0) unique = subscriptions.rm (data + 1, size - 1, pipe_); else unique = subscriptions.add (data + 1, size - 1, pipe_); // If the subscription is not a duplicate store it so that it can be // passed to used on next recv call. if (unique && options.type != ZMQ_PUB) pending.push_back (blob_t (data, size)); } sub.close (); } }
void zmq::xpub_t::xread_activated (pipe_t *pipe_) { // There are some subscriptions waiting. Let's process them. msg_t sub; while (pipe_->read (&sub)) { // Apply the subscription to the trie unsigned char *const data = (unsigned char *) sub.data (); const size_t size = sub.size (); if (size > 0 && (*data == 0 || *data == 1)) { if (manual) { pending_pipes.push_back(pipe_); pending_data.push_back(blob_t(data, size)); pending_metadata.push_back(sub.metadata()); pending_flags.push_back(0); } else { bool unique; if (*data == 0) unique = subscriptions.rm(data + 1, size - 1, pipe_); else unique = subscriptions.add(data + 1, size - 1, pipe_); // If the (un)subscription is not a duplicate store it so that it can be // passed to the user on next recv call unless verbose mode is enabled // which makes to pass always these messages. if (options.type == ZMQ_XPUB && (unique || (*data == 1 && verbose_subs) || (*data == 0 && verbose_unsubs && verbose_subs))) { pending_data.push_back(blob_t(data, size)); pending_metadata.push_back(sub.metadata()); pending_flags.push_back(0); } } } else { // Process user message coming upstream from xsub socket pending_data.push_back (blob_t (data, size)); pending_metadata.push_back (sub.metadata ()); pending_flags.push_back (sub.flags ()); } sub.close (); } }
void zmq::zmq_init_t::detach () { // This function is called by engine when disconnection occurs. // If there is an associated session, send it a null engine to let it know // that connection process was unsuccesful. if (session) send_attach (session, NULL, blob_t (), true); // The engine will destroy itself, so let's just drop the pointer here and // start termination of the init object. engine = NULL; terminate (); }
bool zmq::router_t::identify_peer (pipe_t *pipe_) { msg_t msg; blob_t identity; msg.init (); bool ok = pipe_->read (&msg); if (!ok) return false; if (msg.size () == 0) { // Fall back on the auto-generation unsigned char buf [5]; buf [0] = 0; put_uint32 (buf + 1, next_peer_id++); identity = blob_t (buf, sizeof buf); msg.close (); } else { identity = blob_t ((unsigned char*) msg.data (), msg.size ()); outpipes_t::iterator it = outpipes.find (identity); msg.close (); // Ignore peers with duplicate ID. if (it != outpipes.end ()) return false; } pipe_->set_identity (identity); // Add the record into output pipes lookup table outpipe_t outpipe = {pipe_, true}; ok = outpipes.insert (outpipes_t::value_type (identity, outpipe)).second; zmq_assert (ok); return true; }
inline int get_data_blob::operator()(int req, size_t col, variant& var) { T_CCI_BIT data; int ind(-1); const int r(lib::singleton().p_cci_get_data(req, int(col + 1), CCI_A_TYPE_BIT, &data, &ind)); if (lib::error(r) || ind < 0) var = null_t(); else { var = blob_t(); blob_t& blob(::boost::get<blob_t>(var)); blob.resize(data.size); if (!blob.empty()) memcpy(blob.data(), data.buf, data.size); } return r; } // get_data_blob::
bool zmq::pipe_t::read (msg_t *msg_) { if (unlikely (!in_active)) return false; if (unlikely (state != active && state != waiting_for_delimiter)) return false; read_message: if (!inpipe->read (msg_)) { in_active = false; return false; } // If this is a credential, save a copy and receive next message. if (unlikely (msg_->is_credential ())) { const unsigned char *data = static_cast <const unsigned char *> (msg_->data ()); credential = blob_t (data, msg_->size ()); const int rc = msg_->close (); zmq_assert (rc == 0); goto read_message; } // If delimiter was read, start termination process of the pipe. if (msg_->is_delimiter ()) { process_delimiter (); return false; } if (!(msg_->flags () & msg_t::more) && !msg_->is_identity ()) msgs_read++; if (lwm > 0 && msgs_read % lwm == 0) send_activate_write (peer, msgs_read); return true; }
zmq::blob_t zmq::socket_base_t::get_credential () const { return blob_t (); }
int zmq::socket_base_t::connect (const char *addr_) { if (unlikely (ctx_terminated)) { errno = ETERM; return -1; } // Parse addr_ string. std::string protocol; std::string address; int rc = parse_uri (addr_, protocol, address); if (rc != 0) return -1; rc = check_protocol (protocol); if (rc != 0) return -1; if (protocol == "inproc" || protocol == "sys") { // TODO: inproc connect is specific with respect to creating pipes // as there's no 'reconnect' functionality implemented. Once that // is in place we should follow generic pipe creation algorithm. // Find the peer endpoint. endpoint_t peer = find_endpoint (addr_); if (!peer.socket) return -1; reader_t *inpipe_reader = NULL; writer_t *inpipe_writer = NULL; reader_t *outpipe_reader = NULL; writer_t *outpipe_writer = NULL; // The total HWM for an inproc connection should be the sum of // the binder's HWM and the connector's HWM. (Similarly for the // SWAP.) int64_t hwm; if (options.hwm == 0 || peer.options.hwm == 0) hwm = 0; else hwm = options.hwm + peer.options.hwm; int64_t swap; if (options.swap == 0 && peer.options.swap == 0) swap = 0; else swap = options.swap + peer.options.swap; // Create inbound pipe, if required. if (options.requires_in) create_pipe (this, peer.socket, hwm, swap, &inpipe_reader, &inpipe_writer); // Create outbound pipe, if required. if (options.requires_out) create_pipe (peer.socket, this, hwm, swap, &outpipe_reader, &outpipe_writer); // Attach the pipes to this socket object. attach_pipes (inpipe_reader, outpipe_writer, peer.options.identity); // Attach the pipes to the peer socket. Note that peer's seqnum // was incremented in find_endpoint function. We don't need it // increased here. send_bind (peer.socket, outpipe_reader, inpipe_writer, options.identity, false); return 0; } // Choose the I/O thread to run the session in. io_thread_t *io_thread = choose_io_thread (options.affinity); if (!io_thread) { errno = EMTHREAD; return -1; } // Create session. connect_session_t *session = new (std::nothrow) connect_session_t ( io_thread, this, options, protocol.c_str (), address.c_str ()); alloc_assert (session); // If 'immediate connect' feature is required, we'll create the pipes // to the session straight away. Otherwise, they'll be created by the // session once the connection is established. if (options.immediate_connect) { reader_t *inpipe_reader = NULL; writer_t *inpipe_writer = NULL; reader_t *outpipe_reader = NULL; writer_t *outpipe_writer = NULL; // Create inbound pipe, if required. if (options.requires_in) create_pipe (this, session, options.hwm, options.swap, &inpipe_reader, &inpipe_writer); // Create outbound pipe, if required. if (options.requires_out) create_pipe (session, this, options.hwm, options.swap, &outpipe_reader, &outpipe_writer); // Attach the pipes to the socket object. attach_pipes (inpipe_reader, outpipe_writer, blob_t ()); // Attach the pipes to the session object. session->attach_pipes (outpipe_reader, inpipe_writer, blob_t ()); } // Activate the session. Make it a child of this socket. launch_child (session); return 0; }
bool zmq::router_t::identify_peer (pipe_t *pipe_) { msg_t msg; blob_t identity; bool ok; if (connect_rid.length()) { identity = blob_t ((unsigned char*) connect_rid.c_str (), connect_rid.length()); connect_rid.clear (); outpipes_t::iterator it = outpipes.find (identity); if (it != outpipes.end ()) zmq_assert(false); // Not allowed to duplicate an existing rid } else if (options.raw_sock) { // Always assign identity for raw-socket unsigned char buf [5]; buf [0] = 0; put_uint32 (buf + 1, next_rid++); identity = blob_t (buf, sizeof buf); } else if (!options.raw_sock) { // Pick up handshake cases and also case where next identity is set msg.init (); ok = pipe_->read (&msg); if (!ok) return false; if (msg.size () == 0) { // Fall back on the auto-generation unsigned char buf [5]; buf [0] = 0; put_uint32 (buf + 1, next_rid++); identity = blob_t (buf, sizeof buf); msg.close (); } else { identity = blob_t ((unsigned char*) msg.data (), msg.size ()); outpipes_t::iterator it = outpipes.find (identity); msg.close (); if (it != outpipes.end ()) { if (!handover) // Ignore peers with duplicate ID return false; else { // We will allow the new connection to take over this // identity. Temporarily assign a new identity to the // existing pipe so we can terminate it asynchronously. unsigned char buf [5]; buf [0] = 0; put_uint32 (buf + 1, next_rid++); blob_t new_identity = blob_t (buf, sizeof buf); it->second.pipe->set_identity (new_identity); outpipe_t existing_outpipe = {it->second.pipe, it->second.active}; ok = outpipes.insert (outpipes_t::value_type ( new_identity, existing_outpipe)).second; zmq_assert (ok); // Remove the existing identity entry to allow the new // connection to take the identity. outpipes.erase (it); existing_outpipe.pipe->terminate (true); } } } } pipe_->set_identity (identity); // Add the record into output pipes lookup table outpipe_t outpipe = {pipe_, true}; ok = outpipes.insert (outpipes_t::value_type (identity, outpipe)).second; zmq_assert (ok); return true; }
int zmq::socket_base_t::connect (const char *addr_) { if (unlikely (ctx_terminated)) { errno = ETERM; return -1; } // Parse addr_ string. std::string protocol; std::string address; int rc = parse_uri (addr_, protocol, address); if (rc != 0) return -1; // Checks that protocol is valid and supported on this system rc = check_protocol (protocol); if (rc != 0) return -1; // Parsed address for validation sockaddr_storage addr; socklen_t addr_len; if (protocol == "tcp") rc = resolve_ip_hostname (&addr, &addr_len, address.c_str ()); else if (protocol == "ipc") rc = resolve_local_path (&addr, &addr_len, address.c_str ()); if (rc != 0) return -1; if (protocol == "inproc" || protocol == "sys") { // TODO: inproc connect is specific with respect to creating pipes // as there's no 'reconnect' functionality implemented. Once that // is in place we should follow generic pipe creation algorithm. // Find the peer endpoint. endpoint_t peer = find_endpoint (addr_); if (!peer.socket) return -1; // The total HWM for an inproc connection should be the sum of // the binder's HWM and the connector's HWM. int sndhwm; int rcvhwm; if (options.sndhwm == 0 || peer.options.rcvhwm == 0) sndhwm = 0; else sndhwm = options.sndhwm + peer.options.rcvhwm; if (options.rcvhwm == 0 || peer.options.sndhwm == 0) rcvhwm = 0; else rcvhwm = options.rcvhwm + peer.options.sndhwm; // Create a bi-directional pipe to connect the peers. object_t *parents [2] = {this, peer.socket}; pipe_t *pipes [2] = {NULL, NULL}; int hwms [2] = {sndhwm, rcvhwm}; bool delays [2] = {options.delay_on_disconnect, options.delay_on_close}; int rc = pipepair (parents, pipes, hwms, delays); errno_assert (rc == 0); // Attach local end of the pipe to this socket object. attach_pipe (pipes [0], peer.options.identity); // Attach remote end of the pipe to the peer socket. Note that peer's // seqnum was incremented in find_endpoint function. We don't need it // increased here. send_bind (peer.socket, pipes [1], options.identity, false); return 0; } // Choose the I/O thread to run the session in. io_thread_t *io_thread = choose_io_thread (options.affinity); if (!io_thread) { errno = EMTHREAD; return -1; } // Create session. connect_session_t *session = new (std::nothrow) connect_session_t ( io_thread, this, options, protocol.c_str (), address.c_str ()); alloc_assert (session); // If 'immediate connect' feature is required, we'll create the pipes // to the session straight away. Otherwise, they'll be created by the // session once the connection is established. if (options.immediate_connect) { // Create a bi-directional pipe. object_t *parents [2] = {this, session}; pipe_t *pipes [2] = {NULL, NULL}; int hwms [2] = {options.sndhwm, options.rcvhwm}; bool delays [2] = {options.delay_on_disconnect, options.delay_on_close}; int rc = pipepair (parents, pipes, hwms, delays); errno_assert (rc == 0); // Attach local end of the pipe to the socket object. attach_pipe (pipes [0], blob_t ()); // Attach remote end of the pipe to the session object later on. session->attach_pipe (pipes [1]); } // Activate the session. Make it a child of this socket. launch_child (session); return 0; }
void zmq::mechanism_t::set_peer_identity (const void *id_ptr, size_t id_size) { identity = blob_t (static_cast <const unsigned char*> (id_ptr), id_size); }
void zmq::connect_session_t::start_connecting (bool wait_) { // 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 the connecter object. // Both TCP and IPC transports are using the same infrastructure. if (protocol == "tcp" || protocol == "ipc") { zmq_connecter_t *connecter = new (std::nothrow) zmq_connecter_t ( io_thread, this, options, protocol.c_str (), address.c_str (), wait_); alloc_assert (connecter); launch_child (connecter); return; } #if defined ZMQ_HAVE_OPENPGM // Both PGM and EPGM transports are using the same infrastructure. if (protocol == "pgm" || protocol == "epgm") { // For EPGM transport with UDP encapsulation of PGM is used. bool udp_encapsulation = (protocol == "epgm"); // At this point we'll create message pipes to the session straight // away. There's no point in delaying it as no concept of 'connect' // exists with PGM anyway. if (options.type == ZMQ_PUB || options.type == ZMQ_XPUB) { // PGM sender. pgm_sender_t *pgm_sender = new (std::nothrow) pgm_sender_t ( io_thread, options); alloc_assert (pgm_sender); int rc = pgm_sender->init (udp_encapsulation, address.c_str ()); zmq_assert (rc == 0); send_attach (this, pgm_sender, blob_t ()); } else if (options.type == ZMQ_SUB || options.type == ZMQ_XSUB) { // PGM receiver. pgm_receiver_t *pgm_receiver = new (std::nothrow) pgm_receiver_t ( io_thread, options); alloc_assert (pgm_receiver); int rc = pgm_receiver->init (udp_encapsulation, address.c_str ()); zmq_assert (rc == 0); send_attach (this, pgm_receiver, blob_t ()); } else zmq_assert (false); return; } #endif zmq_assert (false); }
int zmq::socket_base_t::connect (const char *addr_) { if (unlikely (app_thread->is_terminated ())) { errno = ETERM; return -1; } // Parse addr_ string. std::string addr_type; std::string addr_args; std::string addr (addr_); std::string::size_type pos = addr.find ("://"); if (pos == std::string::npos) { errno = EINVAL; return -1; } addr_type = addr.substr (0, pos); addr_args = addr.substr (pos + 3); if (addr_type == "inproc") { // TODO: inproc connect is specific with respect to creating pipes // as there's no 'reconnect' functionality implemented. Once that // is in place we should follow generic pipe creation algorithm. // Find the peer socket. socket_base_t *peer = find_endpoint (addr_args.c_str ()); if (!peer) return -1; pipe_t *in_pipe = NULL; pipe_t *out_pipe = NULL; // Create inbound pipe, if required. if (options.requires_in) { in_pipe = new (std::nothrow) pipe_t (this, peer, options.hwm); zmq_assert (in_pipe); } // Create outbound pipe, if required. if (options.requires_out) { out_pipe = new (std::nothrow) pipe_t (peer, this, options.hwm); zmq_assert (out_pipe); } // Attach the pipes to this socket object. attach_pipes (in_pipe ? &in_pipe->reader : NULL, out_pipe ? &out_pipe->writer : NULL, blob_t ()); // Attach the pipes to the peer socket. Note that peer's seqnum // was incremented in find_endpoint function. The callee is notified // about the fact via the last parameter. send_bind (peer, out_pipe ? &out_pipe->reader : NULL, in_pipe ? &in_pipe->writer : NULL, options.identity, false); return 0; } // Create unnamed session. io_thread_t *io_thread = choose_io_thread (options.affinity); session_t *session = new (std::nothrow) session_t (io_thread, this, options); zmq_assert (session); // If 'immediate connect' feature is required, we'll created the pipes // to the session straight away. Otherwise, they'll be created by the // session once the connection is established. if (options.immediate_connect) { pipe_t *in_pipe = NULL; pipe_t *out_pipe = NULL; // Create inbound pipe, if required. if (options.requires_in) { in_pipe = new (std::nothrow) pipe_t (this, session, options.hwm); zmq_assert (in_pipe); } // Create outbound pipe, if required. if (options.requires_out) { out_pipe = new (std::nothrow) pipe_t (session, this, options.hwm); zmq_assert (out_pipe); } // Attach the pipes to the socket object. attach_pipes (in_pipe ? &in_pipe->reader : NULL, out_pipe ? &out_pipe->writer : NULL, blob_t ()); // Attach the pipes to the session object. session->attach_pipes (out_pipe ? &out_pipe->reader : NULL, in_pipe ? &in_pipe->writer : NULL, blob_t ()); } // Activate the session. send_plug (session); send_own (this, session); if (addr_type == "tcp" || addr_type == "ipc") { #if defined ZMQ_HAVE_WINDOWS || defined ZMQ_HAVE_OPENVMS // Windows named pipes are not compatible with Winsock API. // There's no UNIX domain socket implementation on OpenVMS. if (addr_type == "ipc") { errno = EPROTONOSUPPORT; return -1; } #endif // Create the connecter object. Supply it with the session name // so that it can bind the new connection to the session once // it is established. zmq_connecter_t *connecter = new (std::nothrow) zmq_connecter_t ( choose_io_thread (options.affinity), this, options, session->get_ordinal (), false); zmq_assert (connecter); int rc = connecter->set_address (addr_type.c_str(), addr_args.c_str ()); if (rc != 0) { delete connecter; return -1; } send_plug (connecter); send_own (this, connecter); return 0; } #if defined ZMQ_HAVE_OPENPGM if (addr_type == "pgm" || addr_type == "epgm") { // If the socket type requires bi-directional communication // multicast is not an option (it is uni-directional). if (options.requires_in && options.requires_out) { errno = ENOCOMPATPROTO; return -1; } // For epgm, pgm transport with UDP encapsulation is used. bool udp_encapsulation = (addr_type == "epgm"); // At this point we'll create message pipes to the session straight // away. There's no point in delaying it as no concept of 'connect' // exists with PGM anyway. if (options.requires_out) { // PGM sender. pgm_sender_t *pgm_sender = new (std::nothrow) pgm_sender_t ( choose_io_thread (options.affinity), options); zmq_assert (pgm_sender); int rc = pgm_sender->init (udp_encapsulation, addr_args.c_str ()); if (rc != 0) { delete pgm_sender; return -1; } send_attach (session, pgm_sender, blob_t ()); } else if (options.requires_in) { // PGM receiver. pgm_receiver_t *pgm_receiver = new (std::nothrow) pgm_receiver_t ( choose_io_thread (options.affinity), options); zmq_assert (pgm_receiver); int rc = pgm_receiver->init (udp_encapsulation, addr_args.c_str ()); if (rc != 0) { delete pgm_receiver; return -1; } send_attach (session, pgm_receiver, blob_t ()); } else zmq_assert (false); return 0; } #endif // Unknown protoco. errno = EPROTONOSUPPORT; return -1; }
void zmq::object_t::process_command (command_t &cmd_) { switch (cmd_.type) { case command_t::revive: process_revive (); break; case command_t::stop: process_stop (); break; case command_t::plug: process_plug (); process_seqnum (); return; case command_t::own: process_own (cmd_.args.own.object); process_seqnum (); break; case command_t::attach: process_attach (cmd_.args.attach.engine, blob_t (cmd_.args.attach.peer_identity, cmd_.args.attach.peer_identity_size)); process_seqnum (); break; case command_t::bind: process_bind (cmd_.args.bind.in_pipe, cmd_.args.bind.out_pipe, cmd_.args.bind.peer_identity ? blob_t (cmd_.args.bind.peer_identity, cmd_.args.bind.peer_identity_size) : blob_t ()); process_seqnum (); break; case command_t::reader_info: process_reader_info (cmd_.args.reader_info.msgs_read); break; case command_t::pipe_term: process_pipe_term (); return; case command_t::pipe_term_ack: process_pipe_term_ack (); break; case command_t::term_req: process_term_req (cmd_.args.term_req.object); break; case command_t::term: process_term (); break; case command_t::term_ack: process_term_ack (); break; default: zmq_assert (false); } // The assumption here is that each command is processed once only, // so deallocating it after processing is all right. deallocate_command (&cmd_); }
void zmq::object_t::process_command (command_t &cmd_) { switch (cmd_.type) { case command_t::activate_read: process_activate_read (); break; case command_t::activate_write: process_activate_write (cmd_.args.activate_write.msgs_read); break; case command_t::stop: process_stop (); break; case command_t::plug: process_plug (); process_seqnum (); break; case command_t::own: process_own (cmd_.args.own.object); process_seqnum (); break; case command_t::attach: process_attach (cmd_.args.attach.engine, cmd_.args.attach.peer_identity ? blob_t (cmd_.args.attach.peer_identity, cmd_.args.attach.peer_identity_size) : blob_t ()); process_seqnum (); break; case command_t::bind: process_bind (cmd_.args.bind.pipe, cmd_.args.bind.peer_identity ? blob_t (cmd_.args.bind.peer_identity, cmd_.args.bind.peer_identity_size) : blob_t ()); process_seqnum (); break; case command_t::hiccup: process_hiccup (cmd_.args.hiccup.pipe); break; case command_t::pipe_term: process_pipe_term (); break; case command_t::pipe_term_ack: process_pipe_term_ack (); break; case command_t::term_req: process_term_req (cmd_.args.term_req.object); break; case command_t::term: process_term (cmd_.args.term.linger); break; case command_t::term_ack: process_term_ack (); break; case command_t::reap: process_reap (cmd_.args.reap.socket); break; case command_t::reaped: process_reaped (); break; default: zmq_assert (false); } // The assumption here is that each command is processed once only, // so deallocating it after processing is all right. deallocate_command (&cmd_); }