diff --git a/src/server.c b/src/server.c index d5ab115..d73b128 100644 --- a/src/server.c +++ b/src/server.c @@ -18,29 +18,26 @@ #include #include - - typedef struct { - sigset_t *set; // set dei segnali da gestire (mascherati) - int signal_pipe; // descrittore di scrittura di una pipe senza nome + sigset_t *set; // set of signals to handle (masked) + int signal_pipe; // unnamed pipe's descriptor } sigHandler_t; -// funzione eseguita dal signal handler thread +// signal handler thread function static void *sigHandler(void *arg); static void usage(const char *argv0) { - fprintf(stderr, "use: %s \n", argv0); + fprintf(stderr, "Uso: %s \n", argv0); } static void checkargs(int argc, char* argv[]) { - // TODO change all this if (argc != 2) { usage(argv[0]); _exit(EXIT_FAILURE); } ini_t *config = ini_load(argv[1]); - if ( config == NULL) { - fprintf(stderr, "ERROR: unable to read config file\n"); + if (config == NULL) { + fprintf(stderr, "Error: reading config file.\n"); usage(argv[0]); _exit(EXIT_FAILURE); } @@ -66,14 +63,12 @@ int main(int argc, char *argv[]) { sigset_t mask; sigfillset(&mask); - sigdelset(&mask, SIGPIPE); // tolgo soltanto la sigpipe + sigdelset(&mask, SIGPIPE); // only sigpipe is excluded if (pthread_sigmask(SIG_SETMASK, &mask, NULL) != 0) { - fprintf(stderr, "ERROR setting mask\n"); + fprintf(stderr, "Error: setting mask.\n"); goto _cleanup_beforesigthread; } - - // ignoro SIGPIPE per evitare di essere terminato da una scrittura su un socket struct sigaction s; memset(&s, 0, sizeof(s)); s.sa_handler = SIG_IGN; @@ -82,22 +77,21 @@ int main(int argc, char *argv[]) { goto _cleanup_beforesigthread; } - // remove("mysock"); maybe necessary??? + (void) unlink(socketName); - - // creo la struttura per il log + // create structure for logging taglia = taglia_init(logFile, 0); - free(logFile); // free del nome del file + free(logFile); // free the name of the file if(taglia==NULL) { perror("taglia_init"); goto _cleanup_beforesigthread; } - // risorse per il logfile usate nel main + // buffer for loggin char buf[2048]; int n; - - // pipes di comunicazione fra thread main e sigHandler thread/threadF threads + // pipes for comunication between main thread, sigHandler thread + // and worker threads int signal_pipe[2]; int request_pipe[2]; if (pipe(signal_pipe) == -1) { @@ -110,33 +104,32 @@ int main(int argc, char *argv[]) { } - - // thread per la gestione delle interruzioni + // thread for handling interruptions pthread_t sighandler_thread; sigHandler_t handlerArgs = { &mask, signal_pipe[1] }; if (pthread_create(&sighandler_thread, NULL, sigHandler, &handlerArgs) != 0) { - fprintf(stderr, "ERROR creating signal handler thread\n"); + fprintf(stderr, "Error: creating signal handler thread.\n"); goto _cleanup; } - // scrivo sul log + // write to logfile n = snprintf(buf, sizeof(buf), "Creato signal thread con id: %ld\n", (long) sighandler_thread); if( n<0 ) { perror("snprintf"); goto _cleanup; } - if( taglia_log(taglia, buf) < 0) + if(taglia_log(taglia, buf) < 0) goto _cleanup; - // creo lock per operazioni su file + // lock for operations on files pthread_mutex_t lock; if (pthread_mutex_init(&lock, NULL) != 0) { perror("pthread_mutex_init lock"); goto _cleanup; } - // creo socket + // create socket int listenfd; if ((listenfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { perror("socket"); @@ -157,7 +150,7 @@ int main(int argc, char *argv[]) { goto _cleanup; } - // scrivo sul log + // write to logfile n = snprintf(buf, sizeof(buf), "Creato socket: %s\n", socketName); if( n<0 ) { perror("snprintf"); @@ -167,44 +160,47 @@ int main(int argc, char *argv[]) { goto _cleanup; - // creo la queue + // create queue queue = createQueue(maxFiles, maxSize); - // creo la lista dei client in attesa a una lock + // create queue for clients waiting on a lock waiting_t *waiting = NULL; - // creo la threadpool + // create threadpool threadpool_t *pool = NULL; pool = createThreadPool(threadsInPool, pendingSize); if (!pool) { - fprintf(stderr, "ERROR creating thread pool\n"); + fprintf(stderr, "Error: creating thread pool.\n"); goto _cleanup; } - // scrivo sul log + // write to logfile n = snprintf(buf, sizeof(buf), "Creato threadpool di dimensione %d e pending size %d\n", threadsInPool, pendingSize); - if( n<0 ) { + if(n<0) { perror("snprintf"); goto _cleanup; } - if( taglia_log(taglia, buf) < 0) + if(taglia_log(taglia, buf) < 0) goto _cleanup; + + // selector fd_set set, tmpset; FD_ZERO(&set); FD_ZERO(&tmpset); - FD_SET(listenfd, &set); // aggiungo il listener fd al master set - FD_SET(signal_pipe[0], &set); // aggiungo il descrittore di lettura della signal_pipe - FD_SET(request_pipe[0], &set); // aggiungo il descrittore di lettura della request_pipe + // add fd for socket, signal pipe and request pipe. + FD_SET(listenfd, &set); + FD_SET(signal_pipe[0], &set); + FD_SET(request_pipe[0], &set); - // tengo traccia del file descriptor con id piu' grande + // get max file descriptor int fdmax = (listenfd > signal_pipe[0]) ? listenfd : signal_pipe[0]; fdmax = (fdmax > request_pipe[0]) ? fdmax : request_pipe[0]; - // scrivo sul log + // write to logfile n = snprintf(buf, sizeof(buf), "File Server ready.\n\tMaxFiles: %d\n\tMaxSize: %d\n", maxFiles, maxSize); if( n<0 ) { perror("snprintf"); @@ -217,29 +213,28 @@ int main(int argc, char *argv[]) { fflush(stdout); - volatile int quit = 0; - volatile int stopNewConnections = 0; // true to stop new connections + volatile int stopNewConnections = 0; volatile int numberOfConnections = 0; while(!quit) { - // copio il set nella variabile temporanea per la select + // copy the set in the tmp variable for the select tmpset = set; if (select(fdmax+1, &tmpset, NULL, NULL, NULL) == -1) { perror("select"); goto _cleanup; } - // cerchiamo di capire da quale fd abbiamo ricevuto una richiesta + // search for the ready fd for(long i=0; i <= fdmax; ++i) { if (FD_ISSET(i, &tmpset)) { long* connfd = malloc(sizeof(long)); if (!connfd) { - perror("ERROR FATAL malloc"); + perror("malloc"); goto _cleanup; } - if (i == listenfd) { // e' una nuova richiesta di connessione - if(stopNewConnections) { // non vogliamo nuove connessioni - // scrivo sul log + if (i == listenfd) { // new request for connection + if(stopNewConnections) { // no new connections allowed + // write to logfile if( taglia_log(taglia, "Nuova connessione rifiutata, server in terminazione\n") < 0) { free(connfd); goto _cleanup; @@ -251,30 +246,29 @@ int main(int argc, char *argv[]) { continue; } - // accetto la connessione nuova + // accept new connection if ((*connfd = accept(listenfd, (struct sockaddr*)NULL ,NULL)) == -1) { perror("accept"); free(connfd); goto _cleanup; } - - // scrivo sul log + // write to logfile n = snprintf(buf, sizeof(buf), "Nuovo client: %ld\n", *connfd); if( n<0 ) { perror("snprintf"); free(connfd); goto _cleanup; } - if( taglia_log(taglia, buf) < 0) { + if(taglia_log(taglia, buf) < 0) { free(connfd); goto _cleanup; } - // creo gli argomenti da passare al thread + // create args to pass to the worker threadT* args = calloc(1, sizeof(threadT)); if(!args) { - perror("ERROR FATAL calloc"); + perror("calloc"); free(connfd); goto _cleanup; } @@ -287,23 +281,23 @@ int main(int argc, char *argv[]) { args->lock = &lock; args->waiting = &waiting; - // aggiungo al threadpool + // add to threadpool int r = addToThreadPool(pool, threadF, args); - if (r == 0) { + if (r == 0) { // no errors numberOfConnections++; free(connfd); - continue; // aggiunto con successo + continue; } - if (r < 0) // errore interno - fprintf(stderr, "ERROR FATAL adding to the thread pool\n"); - else // coda dei pendenti piena - fprintf(stderr, "ERROR SERVER TOO BUSY\n"); + if (r < 0) // internal error + fprintf(stderr, "Error: adding to the thread pool.\n"); + else // pending queue full + fprintf(stderr, "Error: server too busy.\n"); close(*connfd); free(connfd); continue; } - if (i == request_pipe[0]) { // un worker ha finito di servire un client - long pdr; // ottengo il descrittore della pipe + if (i == request_pipe[0]) { // worker finished task + long pdr; // get pipe descriptor if (readn(request_pipe[0], &pdr, sizeof(long)) == -1) { perror("readn"); free(connfd); @@ -313,8 +307,8 @@ int main(int argc, char *argv[]) { case -1: // client disconnected --numberOfConnections; if (stopNewConnections && numberOfConnections <= 0) { + // quitting and terminating signalThread quit = 1; - // termino il signalThread pthread_cancel(sighandler_thread); break; } @@ -330,7 +324,7 @@ int main(int argc, char *argv[]) { free(connfd); continue; } - if (i == signal_pipe[0]) { // controllo se devo terminare + if (i == signal_pipe[0]) { // check if we need to terminate int code; if (readn(signal_pipe[0], &code, sizeof(int)) == -1) { perror("readn"); @@ -338,24 +332,24 @@ int main(int argc, char *argv[]) { break; } switch (code) { - case 0: { // stop alle connessioni + case 0: { // stop to new connections stopNewConnections = 1; - // scrivo sul log - if( taglia_log(taglia, "Stop new connections\n") < 0){ + // write to logfile + if(taglia_log(taglia, "Stop new connections\n") < 0){ free(connfd); goto _cleanup; } - if (numberOfConnections == 0) { + if(numberOfConnections == 0) { quit = 1; - // termino il signalThread + // stop signalThread pthread_cancel(sighandler_thread); } break; } - case 1: { // stop immediato + case 1: { // immediate stop quit = 1; - // scrivo sul log + // write to logfile if( taglia_log(taglia, "Immediate quit\n") < 0) { free(connfd); goto _cleanup; @@ -363,21 +357,22 @@ int main(int argc, char *argv[]) { break; } default: - perror("ERROR codice inviato dal sigThread invalido.\n"); + perror(NULL); + fprintf(stderr, "Error: invalid code recived from sigThread.\n"); break; } free(connfd); break; } - else { // richiesta di un client giĆ  connesso + else { // request from an already connected client FD_CLR(i, &set); fdmax = (i>fdmax)?i:fdmax; - // creo gli argomenti da passare al thread + // create args for worker thread threadT* args = calloc(1, sizeof(threadT)); if(!args) { - perror("ERROR FATAL calloc"); + perror("calloc"); free(connfd); goto _cleanup; } @@ -390,16 +385,16 @@ int main(int argc, char *argv[]) { args->lock = &lock; args->waiting = &waiting; - // aggiungo al threadpool + // add to the threadpool int r = addToThreadPool(pool, threadF, args); if (r == 0) { free(connfd); - continue; // aggiunto con successo + continue; } - if (r < 0) // errore interno - fprintf(stderr, "ERROR FATAL adding to the thread pool\n"); - else // coda dei pendenti piena - fprintf(stderr, "ERROR SERVER TOO BUSY\n"); + if (r < 0) // internal error + fprintf(stderr, "Error: adding to the thread pool.\n"); + else // pending queue full + fprintf(stderr, "Error: server too busy.\n"); close(*connfd); free(connfd); continue; @@ -409,7 +404,7 @@ int main(int argc, char *argv[]) { } fprintf(stdout, "\n"); - destroyThreadPool(pool, 0); // notifico che i thread dovranno uscire + destroyThreadPool(pool, 0); // notify the threads that need to stop clearWaiting(&waiting); // destroy waiting list taglia_stats(taglia, stdout); // print stats @@ -420,11 +415,13 @@ int main(int argc, char *argv[]) { } destroyQueue(queue); - // aspetto la terminazione de signal handler thread + // wait for sigHandler thread pthread_join(sighandler_thread, NULL); + // free log file structure taglia_del(taglia); + // unlink socket unlink(socketName); free(socketName); @@ -447,13 +444,13 @@ _cleanup_beforesigthread: return -1; } -// funzione eseguita dal signal handler thread +// signal handler thread function static void *sigHandler(void *arg) { sigset_t *set = ((sigHandler_t*)arg)->set; int fd_pipe = ((sigHandler_t*)arg)->signal_pipe; if(pthread_sigmask(SIG_SETMASK, set, NULL)) { - fprintf(stderr, "ERROR setting mask\n"); + fprintf(stderr, "Error: setting mask.\n"); return (void*) 1; } @@ -464,14 +461,14 @@ static void *sigHandler(void *arg) { if (r != 0) { errno = r; - perror("FATAL ERROR 'sigwait'"); + perror("sigwait"); return NULL; } switch (sig) { case SIGHUP: code = 0; - // notifico il thread manager di smettere di accettare nuove connessioni in entrata + // notify main thread to stop new connections if (writen(fd_pipe, &code, sizeof(int)) == -1) { perror("writen"); } @@ -479,7 +476,7 @@ static void *sigHandler(void *arg) { case SIGINT: case SIGQUIT: code = 1; - // notifico il thread manager di terminare il server il prima possibile + // notify main thread to stop immediatly if (writen(fd_pipe, &code, sizeof(int)) == -1) { perror("writen"); }