/*0-64 seconds*/ void delay(unsigned long ticks) { unsigned long long lt = jiffers; while(!timeafter(jiffers,(lt+ ticks))); return; }
void do_select(void) { fd_set readfds, writefds; int maxfd, n; netsvc_t *nwalk; active_t *awalk, *aprev; struct timeval now, start; struct timezone tz; struct timeval tmo; char rbuf[4096]; gettimeofday(&start, &tz); do { gettimeofday(&now, &tz); FD_ZERO(&readfds); FD_ZERO(&writefds); maxfd = -1; nwalk = nethead; while (nwalk) { if (nwalk->listenfd) { FD_SET(nwalk->listenfd, &readfds); if (nwalk->listenfd > maxfd) maxfd = nwalk->listenfd; } nwalk = nwalk->next; } awalk = acthead; while (awalk) { if (awalk->fd) { if (!awalk->readdone) { FD_SET(awalk->fd, &readfds); if (awalk->fd > maxfd) maxfd = awalk->fd; } if (timeafter(&awalk->rbegin, &now)) { FD_SET(awalk->fd, &writefds); if (awalk->fd > maxfd) maxfd = awalk->fd; } } awalk = awalk->next; } tmo.tv_sec = 0; tmo.tv_usec = 100000; n = select(maxfd+1, &readfds, &writefds, NULL, &tmo); } while ((n == 0) && ((now.tv_sec - start.tv_sec) < 10)); if (n <= 0) return; gettimeofday(&now, &tz); awalk = acthead; aprev = NULL; while (awalk) { if (awalk->fd && !awalk->readdone && FD_ISSET(awalk->fd, &readfds)) { n = read(awalk->fd, rbuf, sizeof(rbuf)); if (n <= 0) awalk->readdone = 1; } if (awalk->fd && awalk->respptr && FD_ISSET(awalk->fd, &writefds)) { n = write(awalk->fd, awalk->respptr, awalk->bytesleft); if (n > 0) { awalk->respptr += n; awalk->bytesleft -= n; } } else n = 0; if ((awalk->bytesleft == 0) || (n < 0)) { if (awalk->respbuf) free(awalk->respbuf); close(awalk->fd); awalk->fd = 0; } if (awalk->fd) { aprev = awalk; awalk = awalk->next; } else { active_t *tmp = awalk; awalk = awalk->next; if (aprev) aprev->next = awalk; else acthead = awalk; free(tmp); } } nwalk = nethead; while (nwalk) { int newfd; if (nwalk->listenfd && FD_ISSET(nwalk->listenfd, &readfds)) { while ((newfd = accept(nwalk->listenfd, NULL, 0)) > 0) { /* Pick up a new connection */ fcntl(newfd, F_SETFL, O_NONBLOCK); active_t *newitem = (active_t *)malloc(sizeof(active_t)); newitem->fd = newfd; newitem->rbegin.tv_sec = now.tv_sec + nwalk->delay; newitem->rbegin.tv_usec = now.tv_usec + (random() % 1000000); if (newitem->rbegin.tv_usec > 1000000) { newitem->rbegin.tv_usec -= 1000000; newitem->rbegin.tv_sec++; } newitem->svc = nwalk; if (nwalk->response) { newitem->respbuf = strdup(nwalk->response); newitem->respptr = newitem->respbuf; newitem->bytesleft = nwalk->respsize; } else { newitem->respbuf = NULL; newitem->respptr = NULL; newitem->bytesleft = 0; } newitem->readdone = 0; newitem->next = acthead; acthead = newitem; } } nwalk = nwalk->next; } }