Example #1
0
int nn_close (int s)
{
    int rc;

    NN_BASIC_CHECKS;

    /*  TODO: nn_sock_term can take a long time to accomplish. It should not be
        performed under global critical section. */
    nn_glock_lock ();

    /*  Deallocate the socket object. */
    rc = nn_sock_term (self.socks [s]);
    if (nn_slow (rc == -EINTR)) {
        errno = EINTR;
        return -1;
    }

    /*  Remove the socket from the socket table, add it to unused socket
        table. */
    nn_free (self.socks [s]);
    self.socks [s] = NULL;
    self.unused [NN_MAX_SOCKETS - self.nsocks] = s;
    --self.nsocks;

    /*  Destroy the global context if there's no socket remaining. */
    nn_global_term ();

    nn_glock_unlock ();

    return 0;
}
Example #2
0
int nn_close (int s)
{
    int rc;
    struct nn_sock *sock;

    nn_glock_lock ();
    rc = nn_global_hold_socket_locked (&sock, s);
    if (nn_slow (rc < 0)) {
        nn_glock_unlock ();
        errno = -rc;
        return -1;
    }

    /*  Start the shutdown process on the socket.  This will cause
        all other socket users, as well as endpoints, to begin cleaning up.
        This is done with the glock held to ensure that two instances
        of nn_close can't access the same socket. */
    nn_sock_stop (sock);

    /*  We have to drop both the hold we just acquired, as well as
        the original hold, in order for nn_sock_term to complete. */
    nn_sock_rele (sock);
    nn_sock_rele (sock);
    nn_glock_unlock ();

    /*  Now clean up.  The termination routine below will block until
        all other consumers of the socket have dropped their holds, and
        all endpoints have cleanly exited. */
    rc = nn_sock_term (sock);
    if (nn_slow (rc == -EINTR)) {
        nn_global_rele_socket (sock);
        errno = EINTR;
        return -1;
    }

    /*  Remove the socket from the socket table, add it to unused socket
        table. */
    nn_glock_lock ();
    self.socks [s] = NULL;
    self.unused [NN_MAX_SOCKETS - self.nsocks] = s;
    --self.nsocks;
    nn_free (sock);

    /*  Destroy the global context if there's no socket remaining. */
    nn_global_term ();

    nn_glock_unlock ();

    return 0;
}