void *dowork(void *threadarg){ //our worker thread threadargs *contain = (threadargs *) threadarg;//translate our args... pthread_mutex_t *mutex = contain->mutex; while(1){ pthread_mutex_lock(mutex); int numthreads = (contain->numthreads); pthread_cond_t *worker = (contain->worker); int *requests = (contain->requests); while ((*requests) == 0){//make sure its thread safe pthread_cond_wait(worker, mutex); } int nextout = *(contain->nextout); int socket = (*(contain->socketnumber))[nextout];//socket to send info to //fprintf(stderr,"Socket: %d\n", socket); if (socket == -9999){//exit hatch pthread_mutex_unlock(mutex); return NULL; } handlerequest(socket, (*(contain->saddr))[nextout]);//meat and potatos --> it sends out the string and logs the file nextout = ( nextout + 1 ) % numthreads; // find numthreads from arg that is passed (*(contain->socketnumber))[nextout] = nextout;//administrative duties here and down (*requests) = (*requests)-1; pthread_cond_t *producer = (contain->producer); pthread_cond_signal(producer); pthread_mutex_unlock(mutex); } return NULL; }
int main( int argc , char *argv[] ) { int ls , cs ; ls = startserver( argc , argv ) ; while( (cs = accept( ls , NULL , NULL )) > 0 ) handlerequest( cs ) ; perror( "Accept" ) ; }
void serve(int fd) { int clfd, pid; socklen_t clilen; struct sockaddr_in cli_addr; char ipaddr[INET6_ADDRSTRLEN]; const char *s; for (;;) { clilen = sizeof(struct sockaddr_in); clfd = accept(fd, (struct sockaddr *) &cli_addr, &clilen); if (clfd < 0) { perror("error accepting"); exit(1); } pid = fork(); if (pid < 0) { perror("error forking"); exit(1); } else if (pid == 0) { /* we use the fork twice trick to eliminate zombie process */ if ((pid = fork()) < 0) { perror("error forking"); exit(1); } else if (pid > 0) exit(0); close(fd); s = inet_ntop(AF_INET, &(cli_addr.sin_addr), ipaddr, sizeof(ipaddr)); if (!s) { perror("error inet_ntop"); exit(1); } handlerequest(clfd, s); close(clfd); exit(0); } else { close(clfd); waitpid(pid, 0, 0); } } }