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; }
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; }