/** * Main function of the server application. It does a infinite loop unless a user exits the program. * @param[in] listener_socket File descriptor of the socket listening incoming connections. * @param[in] fifo File descriptor of a temporary FIFO file. */ void doServer(int listener_socket, int fifo) { int i, fdmax, newfd; players_list_s *players_list = NULL; games_list_s *games_list = NULL; threads_list_s *threads_list = NULL; pthread_mutex_t players_list_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t games_list_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t threads_list_mutex = PTHREAD_MUTEX_INITIALIZER; fd_set base_rdfs, rdfs; sigset_t mask, oldmask; FD_ZERO(&base_rdfs); FD_SET(listener_socket, &base_rdfs); fdmax = max(listener_socket, fifo); sigemptyset(&mask); sigaddset(&mask, SIGINT); sigprocmask(SIG_BLOCK, &mask, &oldmask); initialize_structures(&players_list, &games_list, &threads_list); printf("Four-in-a-line server started\n"); while (work) { rdfs = base_rdfs; if (pselect(fdmax + 1, &rdfs, NULL, NULL, NULL, &oldmask) > 0) { for (i = 0; i <= fdmax; i++) { newfd = -1; if (FD_ISSET(i, &rdfs)) { if (i == listener_socket) { /* request from newly connected client */ newfd = add_new_client(listener_socket); if (newfd > 0) { FD_SET(newfd, &base_rdfs); if (newfd > fdmax) { fdmax = newfd; } display_log(newfd); communicate(newfd, &base_rdfs, &players_list, &games_list, &threads_list, &players_list_mutex, &games_list_mutex, &threads_list_mutex); } else if (i == fifo) { /* trick to update base_rdfs set */ char temp[1]; bulk_read(fifo, temp, 1); } } else { /* request from already connected client */ communicate(i, &base_rdfs, &players_list, &games_list, &threads_list, &players_list_mutex, &games_list_mutex, &threads_list_mutex); } } } } else { if (EINTR == errno) continue; ERR("pselect"); } } pthread_mutex_destroy(&players_list_mutex); pthread_mutex_destroy(&games_list_mutex); pthread_mutex_destroy(&threads_list_mutex); destroy_players(players_list); destroy_games(games_list); destroy_threads(threads_list); sigprocmask(SIG_UNBLOCK, &mask, NULL); }
int main(int argc, char **argv) { init_needle(argc > 1 ? argv[1] : "GCAACGAGTGTCTTTG"); #ifdef DNA_DEBUG printf("Looking for %s\n", needle); #endif struct timeval start_time; print_current_time(&start_time); printf(" START\n"); bufindex_t input_size = 3000000000L; size_t page_size = sysconf(_SC_PAGESIZE); ASSERT_NOT(page_size & (page_size - 1), "Page is not a power of 2"); size_t mask = page_size - 1; size_t mem_size = (input_size | mask) + 1; buflen_t buf_size = page_size << 14; #ifdef DNA_DEBUG printf("Buf size = %u\n", buf_size);; #endif init_threads(); ALGO_PREPARE #ifdef DNA_DEBUG long io_time, waiting_time; struct timeval tx, ty, tz; print_current_time(&tx); printf(" Start reading data\n"); #endif int fd = 0; if (argc > 2 && (fd = open(argv[2], O_RDONLY)) == -1) ERROR_OCCURRED("open"); char *mapped_file = mmap(NULL, mem_size, PROT_READ, MAP_SHARED, fd, 0); if (fd > 0 && close(fd) == -1) ERROR_OCCURRED("close"); char *buf; bufindex_t start; buflen_t bytes_read; buflen_t len = buf_size + needle_len - 1; for (start = 0, buf = mapped_file; start < input_size; start += buf_size, buf += buf_size) { bytes_read = (start + len < input_size) ? len : input_size - start; job_t *job = malloc(sizeof(job_t)); job->buf = buf; job->len = bytes_read; job->offset = start; submit_job(job); } #ifdef DNA_DEBUG print_current_time(&ty); printf(" End submitting jobs\n"); io_time = calc_elapsed_time(&tx, &ty); #endif wait_jobs_completed(); munmap(mapped_file, mem_size); #ifdef DNA_DEBUG gettimeofday(&tz, NULL); waiting_time = calc_elapsed_time(&ty, &tz); #endif destroy_threads(); ALGO_FREE struct timeval end_time; print_current_time(&end_time); printf(" FINISH\n"); #ifdef DNA_DEBUG print_elapsed_time(&start_time, &end_time); printf("I/O: %ld\n", io_time); printf("Waiting: %ld\n", waiting_time); #endif return 0; }