int main(int argc, char * argv[]) { int sockfd; int newsockfd; char readbuf[SIZE]; char *read_request=malloc(MEMORYSIZE); long int port_num=0,default_port=9000; struct sigaction sa,sa_usr1; sa.sa_flags=0; sa.sa_handler=handle_signal; if(sigaction(SIGINT,&sa,NULL)==-1) exit(EXIT_FAILURE); if(sigaction(SIGTERM,&sa,NULL)==-1) exit(EXIT_FAILURE); sa_usr1.sa_flags=0; sa_usr1.sa_handler=handle_sigusr1; if(sigaction(SIGUSR1,&sa_usr1,NULL)==-1) exit(EXIT_FAILURE); printf("%d\n",getpid()); strategy=getinput(argc,argv,directory_name); printf("%d\n",portno); sockfd=startserver(portno); time(&server_start_time); //printf(ctime(&server_start_time)); if(strategy=='w') { //printf("Calling thread pool with %d %d\n",*thread_num,*buf_size); // active=0; dispatch_to_thread_pool(sockfd,directory_name); } else { while(active) { // check=1; newsockfd=accept(sockfd,(struct sockaddr*)NULL,NULL); if(newsockfd<0) { continue; } request_count++; if(newsockfd>0) dispatch_connection(read_request,strategy,newsockfd,directory_name); } } free(read_request); close(sockfd); printf("graceful exit\n"); return(0); }
/** * pthread compatible routine that handles connections and processes * whatever comes in on those. */ static void * dispatch_runner(void *arg) { dispatcher *self = (dispatcher *)arg; connection *conn; int c; self->metrics = 0; self->blackholes = 0; self->ticks = 0; self->sleeps = 0; self->prevmetrics = 0; self->prevblackholes = 0; self->prevticks = 0; self->prevsleeps = 0; if (self->type == LISTENER) { struct pollfd ufds[sizeof(listeners) / sizeof(connection *)]; while (self->keep_running) { for (c = 0; c < sizeof(listeners) / sizeof(connection *); c++) { if (listeners[c] == NULL) break; ufds[c].fd = listeners[c]->sock; ufds[c].events = POLLIN; } if (poll(ufds, c, 1000) > 0) { for (--c; c >= 0; c--) { if (ufds[c].revents & POLLIN) { int client; struct sockaddr addr; socklen_t addrlen = sizeof(addr); if ((client = accept(ufds[c].fd, &addr, &addrlen)) < 0) { logerr("dispatch: failed to " "accept() new connection: %s\n", strerror(errno)); dispatch_check_rlimit_and_warn(); continue; } if (dispatch_addconnection(client) == -1) { close(client); continue; } } } } } } else if (self->type == CONNECTION) { int work; struct timeval start, stop; while (self->keep_running) { work = 0; if (self->route_refresh_pending) { self->rtr = self->pending_rtr; self->pending_rtr = NULL; self->route_refresh_pending = 0; self->hold = 0; } gettimeofday(&start, NULL); pthread_rwlock_rdlock(&connectionslock); for (c = 0; c < connectionslen; c++) { conn = &(connections[c]); /* atomically try to "claim" this connection */ if (!__sync_bool_compare_and_swap(&(conn->takenby), 0, self->id)) continue; if (self->hold && !conn->isaggr) { conn->takenby = 0; continue; } work += dispatch_connection(conn, self, start); } pthread_rwlock_unlock(&connectionslock); gettimeofday(&stop, NULL); self->ticks += timediff(start, stop); /* nothing done, avoid spinlocking */ if (self->keep_running && work == 0) { gettimeofday(&start, NULL); usleep((100 + (rand() % 200)) * 1000); /* 100ms - 300ms */ gettimeofday(&stop, NULL); self->sleeps += timediff(start, stop); } } } else { logerr("huh? unknown self type!\n"); } return NULL; }
/** * pthread compatible routine that handles connections and processes * whatever comes in on those. */ static void * dispatch_runner(void *arg) { dispatcher *self = (dispatcher *)arg; connection *conn; int work; int c; self->metrics = 0; self->ticks = 0; self->state = SLEEPING; if (self->type == LISTENER) { fd_set fds; int maxfd = -1; struct timeval tv; while (self->keep_running) { FD_ZERO(&fds); tv.tv_sec = 0; tv.tv_usec = 250 * 1000; /* 250 ms */ for (c = 0; c < sizeof(listeners) / sizeof(connection *); c++) { conn = listeners[c]; if (conn == NULL) break; FD_SET(conn->sock, &fds); if (conn->sock > maxfd) maxfd = conn->sock; } if (select(maxfd + 1, &fds, NULL, NULL, &tv) > 0) { for (c = 0; c < sizeof(listeners) / sizeof(connection *); c++) { conn = listeners[c]; if (conn == NULL) break; if (FD_ISSET(conn->sock, &fds)) { int client; struct sockaddr addr; socklen_t addrlen = sizeof(addr); if ((client = accept(conn->sock, &addr, &addrlen)) < 0) { logerr("dispatch: failed to " "accept() new connection: %s\n", strerror(errno)); dispatch_check_rlimit_and_warn(); continue; } if (dispatch_addconnection(client) == -1) { close(client); continue; } } } } } } else if (self->type == CONNECTION) { while (self->keep_running) { work = 0; if (self->route_refresh_pending) { self->routes = self->pending_routes; self->pending_routes = NULL; self->route_refresh_pending = 0; } pthread_rwlock_rdlock(&connectionslock); for (c = 0; c < connectionslen; c++) { conn = &(connections[c]); /* atomically try to "claim" this connection */ if (!__sync_bool_compare_and_swap(&(conn->takenby), 0, self->id)) continue; self->state = RUNNING; work += dispatch_connection(conn, self); } pthread_rwlock_unlock(&connectionslock); self->state = SLEEPING; /* nothing done, avoid spinlocking */ if (self->keep_running && work == 0) usleep((100 + (rand() % 200)) * 1000); /* 100ms - 300ms */ } } else { logerr("huh? unknown self type!\n"); } return NULL; }