void nn_ins_connect (struct nn_ins_item *item, nn_ins_fn fn) { struct nn_list_item *it; struct nn_ins_item *bitem; nn_mutex_lock (&self.sync); /* Insert the entry into the endpoint repository. */ nn_list_insert (&self.connected, &item->item, nn_list_end (&self.connected)); /* During this process a pipe may be created. */ for (it = nn_list_begin (&self.bound); it != nn_list_end (&self.bound); it = nn_list_next (&self.bound, it)) { bitem = nn_cont (it, struct nn_ins_item, item); if (strncmp (nn_epbase_getaddr (&item->epbase), nn_epbase_getaddr (&bitem->epbase), NN_SOCKADDR_MAX) == 0) { /* Check whether the two sockets are compatible. */ if (!nn_epbase_ispeer (&item->epbase, bitem->protocol)) break; /* Call back to cinproc to create actual connection. */ fn (item, bitem); break; } } nn_mutex_unlock (&self.sync); }
static int nn_inproc_bind (const char *addr, void *hint, struct nn_epbase **epbase) { struct nn_list_item *it; struct nn_binproc *binproc; struct nn_cinproc *cinproc; nn_mutex_lock (&self.sync); /* Check whether the endpoint isn't already bound. */ /* TODO: This is an O(n) algorithm! */ for (it = nn_list_begin (&self.bound); it != nn_list_end (&self.bound); it = nn_list_next (&self.bound, it)) { binproc = nn_cont (it, struct nn_binproc, item); if (strncmp (addr, nn_binproc_getaddr (binproc), NN_SOCKADDR_MAX) == 0) { nn_mutex_unlock (&self.sync); return -EADDRINUSE; } } /* Insert the entry into the endpoint repository. */ binproc = nn_binproc_create (hint); nn_list_insert (&self.bound, &binproc->item, nn_list_end (&self.bound)); /* During this process new pipes may be created. */ for (it = nn_list_begin (&self.connected); it != nn_list_end (&self.connected); it = nn_list_next (&self.connected, it)) { cinproc = nn_cont (it, struct nn_cinproc, item); if (strncmp (addr, nn_cinproc_getaddr (cinproc), NN_SOCKADDR_MAX) == 0) { /* Check whether the two sockets are compatible. */ if (!nn_epbase_ispeer (&binproc->epbase, cinproc->protocol)) continue; nn_assert (cinproc->connects == 0); cinproc->connects = 1; nn_binproc_connect (binproc, cinproc); } } nn_assert (epbase); *epbase = &binproc->epbase; nn_mutex_unlock (&self.sync); return 0; }
int nn_ins_bind (struct nn_ins_item *item, nn_ins_fn fn) { struct nn_list_item *it; struct nn_ins_item *bitem; struct nn_ins_item *citem; nn_mutex_lock (&self.sync); /* Check whether the endpoint isn't already bound. */ /* TODO: This is an O(n) algorithm! */ for (it = nn_list_begin (&self.bound); it != nn_list_end (&self.bound); it = nn_list_next (&self.bound, it)) { bitem = nn_cont (it, struct nn_ins_item, item); if (strncmp (nn_epbase_getaddr (&item->epbase), nn_epbase_getaddr (&bitem->epbase), NN_SOCKADDR_MAX) == 0) { nn_mutex_unlock (&self.sync); return -EADDRINUSE; } } /* Insert the entry into the endpoint repository. */ nn_list_insert (&self.bound, &item->item, nn_list_end (&self.bound)); /* During this process new pipes may be created. */ for (it = nn_list_begin (&self.connected); it != nn_list_end (&self.connected); it = nn_list_next (&self.connected, it)) { citem = nn_cont (it, struct nn_ins_item, item); if (strncmp (nn_epbase_getaddr (&item->epbase), nn_epbase_getaddr (&citem->epbase), NN_SOCKADDR_MAX) == 0) { /* Check whether the two sockets are compatible. */ if (!nn_epbase_ispeer (&item->epbase, citem->protocol)) continue; fn (item, citem); } } nn_mutex_unlock (&self.sync); return 0; }
static int nn_inproc_connect (const char *addr, void *hint, struct nn_epbase **epbase) { struct nn_list_item *it; struct nn_cinproc *cinproc; struct nn_binproc *binproc; nn_mutex_lock (&self.sync); /* Insert the entry into the endpoint repository. */ cinproc = nn_cinproc_create (hint); nn_list_insert (&self.connected, &cinproc->item, nn_list_end (&self.connected)); /* During this process a pipe may be created. */ for (it = nn_list_begin (&self.bound); it != nn_list_end (&self.bound); it = nn_list_next (&self.bound, it)) { binproc = nn_cont (it, struct nn_binproc, item); if (strncmp (addr, nn_binproc_getaddr (binproc), NN_SOCKADDR_MAX) == 0) { /* Check whether the two sockets are compatible. */ if (!nn_epbase_ispeer (&cinproc->epbase, binproc->protocol)) break; ++binproc->connects; nn_cinproc_connect (cinproc, binproc); break; } } nn_assert (epbase); *epbase = &cinproc->epbase; nn_mutex_unlock (&self.sync); return 0; }