Пример #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;
}
Пример #2
0
int nn_socket (int domain, int protocol)
{
    int rc;

    nn_glock_lock ();

    /*  If nn_term() was already called, return ETERM. */
    if (nn_slow (self.flags & NN_CTX_FLAG_ZOMBIE)) {
        nn_glock_unlock ();
        errno = ETERM;
        return -1;
    }

    /*  Make sure that global state is initialised. */
    nn_global_init ();

    rc = nn_global_create_socket (domain, protocol);

    if(rc < 0) {
        nn_global_term ();
        nn_glock_unlock ();
        errno = -rc;
        return -1;
    }

    nn_glock_unlock();

    return rc;
}
Пример #3
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;
}
Пример #4
0
int nn_socket (int domain, int protocol)
{
    int rc;
    int s;
    struct nn_list_item *it;
    struct nn_socktype *socktype;
    struct nn_sock *sock;

    nn_glock_lock ();

    /*  Make sure that global state is initialised. */
    nn_global_init ();

    /*  If nn_term() was already called, return ETERM. */
    if (nn_slow (self.flags & NN_CTX_FLAG_ZOMBIE)) {
        nn_global_term ();
        nn_glock_unlock ();
        errno = ETERM;
        return -1;
    }

    /*  Only AF_SP and AF_SP_RAW domains are supported. */
    if (nn_slow (domain != AF_SP && domain != AF_SP_RAW)) {
        nn_global_term ();
        nn_glock_unlock ();
        errno = EAFNOSUPPORT;
        return -1;
    }

    /*  If socket limit was reached, report error. */
    if (nn_slow (self.nsocks >= NN_MAX_SOCKETS)) {
        nn_global_term ();
        nn_glock_unlock ();
        errno = EMFILE;
        return -1;
    }

    /*  Find an empty socket slot. */
    s = self.unused [NN_MAX_SOCKETS - self.nsocks - 1];

    /*  Find the appropriate socket type. */
    for (it = nn_list_begin (&self.socktypes);
          it != nn_list_end (&self.socktypes);
          it = nn_list_next (&self.socktypes, it)) {
        socktype = nn_cont (it, struct nn_socktype, item);
        if (socktype->domain == domain && socktype->protocol == protocol) {

            /*  Instantiate the socket. */
            sock = nn_alloc (sizeof (struct nn_sock), "sock");
            alloc_assert (sock);
            rc = nn_sock_init (sock, socktype);
            if (rc < 0)
                goto error;

            /*  Adjust the global socket table. */
            self.socks [s] = sock;
            ++self.nsocks;
            nn_glock_unlock ();
            return s;
        }
    }
    rc = -EINVAL;

    /*  Specified socket type wasn't found. */
error:
    nn_global_term ();
    nn_glock_unlock ();
    errno = -rc;
    return -1;
}