void dlist_node_tail_push(dlist_t *list, dlist_node_t *node) { assert(list != NULL); assert(list->lock == 0); assert(node != NULL); dlist_assert(list); /* eject the node from whatever list it is currently on */ dlist_node_eject(node->list, node); /* if we don't have a tail node, we don't have a head node set either */ if(list->tail == NULL) { list->head = node; } else { list->tail->next = node; } /* the current tail node will be second to last on the list */ node->prev = list->tail; node->list = list; list->tail = node; list->length++; dlist_assert(list); return; }
/* * fds_select_assemble * * given a list of scamper_fd_poll_t structures held in a list, compose an * fd_set for them to pass to select. */ static fd_set *fds_select_assemble(dlist_t *fds, fd_set *fdset, int *nfds) { scamper_fd_poll_t *fdp; dlist_node_t *node; int count = 0; FD_ZERO(fdset); node = dlist_head_node(fds); while(node != NULL) { /* file descriptor associated with the node */ fdp = (scamper_fd_poll_t *)dlist_node_item(node); /* get the next node incase this node is subsequently removed */ node = dlist_node_next(node); /* if there is nothing using this fdn any longer, then stop polling it */ if(fdp->fdn->refcnt == 0 && fdp->fdn->rc0 == NULL) { fd_refcnt_0(fdp->fdn); continue; } /* if the inactive flag is set, then skip over this file descriptor */ if((fdp->flags & SCAMPER_FD_POLL_FLAG_INACTIVE) != 0) { dlist_node_eject(fds, fdp->node); fdp->list = NULL; continue; } /* monitor this file descriptor */ FD_SET(fdp->fdn->fd, fdset); count++; /* update the maxfd seen if appropriate */ if(*nfds < fdp->fdn->fd) { *nfds = fdp->fdn->fd; } } /* * if there are no fds in the set to monitor, then return a null pointer * to pass to select */ if(count == 0) { return NULL; } return fdset; }