int zmq::socket_base_t::close () { shutting_down = true; // Let the thread know that the socket is no longer available. app_thread->remove_socket (this); // Pointer to the context must be retrieved before the socket is // deallocated. Afterwards it is not available. ctx_t *ctx = get_ctx (); // Unregister all inproc endpoints associated with this socket. // From this point we are sure that inc_seqnum won't be called again // on this object. ctx->unregister_endpoints (this); // Wait till all undelivered commands are delivered. This should happen // very quickly. There's no way to wait here for extensive period of time. while (processed_seqnum != sent_seqnum.get ()) app_thread->process_commands (true, false); while (true) { // On third pass of the loop there should be no more I/O objects // because all connecters and listerners were destroyed during // the first pass and all engines delivered by delayed 'own' commands // are destroyed during the second pass. if (io_objects.empty () && !pending_term_acks) break; // Send termination request to all associated I/O objects. for (io_objects_t::iterator it = io_objects.begin (); it != io_objects.end (); it++) send_term (*it); // Move the objects to the list of pending term acks. pending_term_acks += io_objects.size (); io_objects.clear (); // Process commands till we get all the termination acknowledgements. while (pending_term_acks) app_thread->process_commands (true, false); } // Check whether there are no session leaks. sessions_sync.lock (); zmq_assert (named_sessions.empty ()); zmq_assert (unnamed_sessions.empty ()); sessions_sync.unlock (); delete this; // This function must be called after the socket is completely deallocated // as it may cause termination of the whole 0MQ infrastructure. ctx->destroy_socket (); return 0; }
int close_connection(struct srv_connection *conn){ int i; for(i=0; i<conn->cli_ct; i++){ send_term(conn->cli[i].sfd); close(conn->cli[i].sfd); } close(conn->srv_sfd); }
int main(int argc, char *argv[]) { mpz_t _t_1, _C, _s_1; mpz_init(_t_1); mpz_init(_C); mpz_init(_s_1); init_term(argv[1]); init(); Round0(); Round1(_t_1); gmp_printf("Round1 output: %Zd\n", _t_1); send_term(_t_1); gmp_printf("Round2 input: "); receive_term(_C); gmp_printf("%Zd\n", _C); Round2(_s_1, _C); gmp_printf("Round2 output: %Zd\n", _s_1); send_term(_s_1); clear(); close_term(); mpz_clear(_t_1); mpz_clear(_C); mpz_clear(_s_1); return 0; }
void zmq::own_t::process_own (own_t *object_) { // If the object is already being shut down, new owned objects are // immediately asked to terminate. Note that linger is set to zero. if (terminating) { register_term_acks (1); send_term (object_, 0); return; } // Store the reference to the owned object. owned.insert (object_); }
void zmq::own_t::process_term (int linger_) { // Double termination should never happen. zmq_assert (!terminating); // Send termination request to all owned objects. for (owned_t::iterator it = owned.begin (); it != owned.end (); ++it) send_term (*it, linger_); register_term_acks ((int) owned.size ()); owned.clear (); // Start termination process and check whether by chance we cannot // terminate immediately. terminating = true; check_term_acks (); }
void zmq::socket_base_t::process_term_req (owned_t *object_) { // When shutting down we can ignore termination requests from owned // objects. They are going to be terminated anyway. if (shutting_down) return; // If I/O object is well and alive ask it to terminate. io_objects_t::iterator it = std::find (io_objects.begin (), io_objects.end (), object_); // If not found, we assume that termination request was already sent to // the object so we can sagely ignore the request. if (it == io_objects.end ()) return; pending_term_acks++; io_objects.erase (it); send_term (object_); }
void zmq::own_t::process_term_req (own_t *object_) { // When shutting down we can ignore termination requests from owned // objects. The termination request was already sent to the object. if (terminating) return; // If I/O object is well and alive let's ask it to terminate. owned_t::iterator it = std::find (owned.begin (), owned.end (), object_); // If not found, we assume that termination request was already sent to // the object so we can safely ignore the request. if (it == owned.end ()) return; owned.erase (it); register_term_acks (1); // Note that this object is the root of the (partial shutdown) thus, its // value of linger is used, rather than the value stored by the children. send_term (object_, options.linger); }
static void send_format(char* format) { send_term(erl_format(format)); }