From b4ca73b8d662242e4a01eee79307a5eb1c5fc86b Mon Sep 17 00:00:00 2001 From: elvis Date: Sat, 12 Mar 2022 10:05:58 +0100 Subject: [PATCH] Added server status --- lib/utils/serverStatus.h | 16 +++++++ lib/utils/util.h | 95 ++++++++++++++++++++-------------------- src/server.c | 50 ++++++++++++++++----- src/serverWorker.c | 44 +++++++++++-------- 4 files changed, 129 insertions(+), 76 deletions(-) create mode 100644 lib/utils/serverStatus.h diff --git a/lib/utils/serverStatus.h b/lib/utils/serverStatus.h new file mode 100644 index 0000000..41ea8a1 --- /dev/null +++ b/lib/utils/serverStatus.h @@ -0,0 +1,16 @@ +#pragma once +#ifndef _SERVER_STATUS +#define _SERVER_STATUS + +typedef struct { + pthread_mutex_t *mtx; + pthread_cond_t *cond; + + long max_space_occupied; + long cur_space_occupied; + long max_files; + long cur_files; + char exiting; +} serverStatus; + +#endif /* _SERVER_STATUS */ diff --git a/lib/utils/util.h b/lib/utils/util.h index 5ead69f..0fbec59 100644 --- a/lib/utils/util.h +++ b/lib/utils/util.h @@ -48,7 +48,7 @@ #define CHECK_EQ_EXIT(name, X, val, str, ...) \ if ((X)==val) { \ - perror(#name); \ + perror(#name); \ int errno_copy = errno; \ print_error(str, __VA_ARGS__); \ exit(errno_copy); \ @@ -56,7 +56,7 @@ #define CHECK_NEQ_EXIT(name, X, val, str, ...) \ if ((X)!=val) { \ - perror(#name); \ + perror(#name); \ int errno_copy = errno; \ print_error(str, __VA_ARGS__); \ exit(errno_copy); \ @@ -72,8 +72,8 @@ static inline void print_error(const char * str, ...) { char * p=(char *)malloc(strlen(str)+strlen(err)+EXTRA_LEN_PRINT_ERROR); if (!p) { perror("malloc"); - fprintf(stderr,"FATAL ERROR nella funzione 'print_error'\n"); - return; + fprintf(stderr,"FATAL ERROR nella funzione 'print_error'\n"); + return; } strcpy(p,err); strcpy(p+strlen(err), str); @@ -84,7 +84,7 @@ static inline void print_error(const char * str, ...) { } -/** +/** * \brief Controlla se la stringa passata come primo argomento e' un numero. * \return 0 ok 1 non e' un numbero 2 overflow/underflow */ @@ -97,55 +97,56 @@ static inline int isNumber(const char* s, long* n) { if (errno == ERANGE) return 2; // overflow/underflow if (e != NULL && *e == (char)0) { *n = val; - return 0; // successo + return 0; // successo } return 1; // non e' un numero } -#define LOCK(l) if (pthread_mutex_lock(l)!=0) { \ - fprintf(stderr, "ERRORE FATALE lock\n"); \ - pthread_exit((void*)EXIT_FAILURE); \ - } -#define LOCK_RETURN(l, r) if (pthread_mutex_lock(l)!=0) { \ - fprintf(stderr, "ERRORE FATALE lock\n"); \ - return r; \ - } +#define LOCK(l) if (pthread_mutex_lock(l)!=0) { \ + fprintf(stderr, "ERRORE FATALE lock\n"); \ + pthread_exit((void*)EXIT_FAILURE); \ + } +#define LOCK_RETURN(l, r) if (pthread_mutex_lock(l)!=0) { \ + fprintf(stderr, "ERRORE FATALE lock\n"); \ + return r; \ + } -#define UNLOCK(l) if (pthread_mutex_unlock(l)!=0) { \ - fprintf(stderr, "ERRORE FATALE unlock\n"); \ - pthread_exit((void*)EXIT_FAILURE); \ - } -#define UNLOCK_RETURN(l,r) if (pthread_mutex_unlock(l)!=0) { \ - fprintf(stderr, "ERRORE FATALE unlock\n"); \ - return r; \ - } -#define WAIT(c,l) if (pthread_cond_wait(c,l)!=0) { \ - fprintf(stderr, "ERRORE FATALE wait\n"); \ - pthread_exit((void*)EXIT_FAILURE); \ - } +#define UNLOCK(l) if (pthread_mutex_unlock(l)!=0) { \ + fprintf(stderr, "ERRORE FATALE unlock\n"); \ + pthread_exit((void*)EXIT_FAILURE); \ + } +#define UNLOCK_RETURN(l,r) if (pthread_mutex_unlock(l)!=0) { \ + fprintf(stderr, "ERRORE FATALE unlock\n"); \ + return r; \ + } +#define WAIT(c,l) if (pthread_cond_wait(c,l)!=0) { \ + fprintf(stderr, "ERRORE FATALE wait\n"); \ + pthread_exit((void*)EXIT_FAILURE); \ + } /* ATTENZIONE: t e' un tempo assoluto! */ -#define TWAIT(c,l,t) { \ - int r=0; \ - if ((r=pthread_cond_timedwait(c,l,t))!=0 && r!=ETIMEDOUT) { \ - fprintf(stderr, "ERRORE FATALE timed wait\n"); \ - pthread_exit((void*)EXIT_FAILURE); \ - } \ - } -#define SIGNAL(c) if (pthread_cond_signal(c)!=0) { \ - fprintf(stderr, "ERRORE FATALE signal\n"); \ - pthread_exit((void*)EXIT_FAILURE); \ - } -#define BCAST(c) if (pthread_cond_broadcast(c)!=0) { \ - fprintf(stderr, "ERRORE FATALE broadcast\n"); \ - pthread_exit((void*)EXIT_FAILURE); \ - } +#define TWAIT(c,l,t) { \ + int r=0; \ + if ((r=pthread_cond_timedwait(c,l,t))!=0 && r!=ETIMEDOUT) { \ + fprintf(stderr, "ERRORE FATALE timed wait\n"); \ + pthread_exit((void*)EXIT_FAILURE); \ + } \ + } +#define SIGNAL(c) if (pthread_cond_signal(c)!=0) { \ + fprintf(stderr, "ERRORE FATALE signal\n"); \ + pthread_exit((void*)EXIT_FAILURE); \ + } +#define BCAST(c) if (pthread_cond_broadcast(c)!=0) { \ + fprintf(stderr, "ERRORE FATALE broadcast\n"); \ + pthread_exit((void*)EXIT_FAILURE); \ + } + static inline int TRYLOCK(pthread_mutex_t* l) { - int r=0; - if ((r=pthread_mutex_trylock(l))!=0 && r!=EBUSY) { - fprintf(stderr, "ERRORE FATALE unlock\n"); - pthread_exit((void*)EXIT_FAILURE); - } - return r; + int r=0; + if ((r=pthread_mutex_trylock(l))!=0 && r!=EBUSY) { + fprintf(stderr, "ERRORE FATALE unlock\n"); + pthread_exit((void*)EXIT_FAILURE); + } + return r; } #endif /* _UTIL_H */ diff --git a/src/server.c b/src/server.c index 9a5b890..5831b5a 100644 --- a/src/server.c +++ b/src/server.c @@ -13,6 +13,7 @@ #include #include #include +#include /** @@ -27,6 +28,7 @@ typedef struct { } sigHandler_t; + // funzione eseguita dal signal handler thread static void *sigHandler(void *arg) { sigset_t *set = ((sigHandler_t*)arg)->set; @@ -78,7 +80,7 @@ int main(int argc, char *argv[]) { // TODO read config file checkargs(argc, argv); ini_t *config = ini_load(argv[1]); - int threadsInPool = (int) strtol(ini_get(config, "threadpool", "quantity"), null, 10); + int threadsInPool = (int) strtol(ini_get(config, "threadpool", "quantity"), NULL, 10); ini_free(config); sigset_t mask; @@ -166,8 +168,28 @@ int main(int argc, char *argv[]) { // tengo traccia del file descriptor con id piu' grande int fdmax = (listenfd > signal_pipe[0]) ? listenfd : signal_pipe[0]; - volatile long termina=0; - while(!termina) { + serverStatus* status = malloc(sizeof(serverStatus)); + if (!status) { + // TODO logging utility + perror("ERROR FATAL malloc"); + goto _cleanup; + } + + if (pthread_mutex_init(status->mtx, NULL) != 0) { + fprintf(stderr, "ERRORE: creazione mutex"); + goto _cleanup; + } + if (pthread_cond_init(status->cond, NULL) != 0) { + fprintf(stderr, "ERRORE: creazione condition variable"); + goto _cleanup; + } + status->max_space_occupied = 100000000; // in bytes + status->cur_space_occupied = 0; + status->max_files = 100; + status->cur_files = 0; + status->exiting = 0; + + while(!status->exiting) { // copio il set nella variabile temporanea per la select tmpset = set; if (select(fdmax+1, &tmpset, NULL, NULL, NULL) == -1) { @@ -177,24 +199,30 @@ int main(int argc, char *argv[]) { // cerchiamo di capire da quale fd abbiamo ricevuto una richiesta for(int i=0; i <= fdmax; ++i) { if (FD_ISSET(i, &tmpset)) { - long connfd; + long* connfd = malloc(sizeof(long)); + if (!connfd) { + // TODO logging utility + perror("ERROR FATAL malloc"); + goto _cleanup; + } if (i == listenfd) { // e' una nuova richiesta di connessione - if ((connfd = accept(listenfd, (struct sockaddr*)NULL ,NULL)) == -1) { + if ((*connfd = accept(listenfd, (struct sockaddr*)NULL ,NULL)) == -1) { // TODO logging utility perror("accept"); goto _cleanup; } - long* args = malloc(2*sizeof(long)); + void** args = NULL; + *args = malloc(2*sizeof(void*)); if (!args) { // TODO logging utility perror("ERROR FATAL malloc"); goto _cleanup; } args[0] = connfd; - args[1] = (long)&termina; + args[1] = status; - int r = addToThreadPool(pool, threadF, (void*)args); + int r = addToThreadPool(pool, threadF, args); if (r == 0) continue; // aggiunto con successo if (r < 0)// errore interno @@ -204,17 +232,19 @@ int main(int argc, char *argv[]) { fprintf(stderr, "ERROR SERVER TOO BUSY\n"); // TODO logging utility free(args); - close(connfd); + close(*connfd); + free(connfd); continue; } if (i == signal_pipe[0]) { // ricevuto un segnale, esco ed inizio il protocollo di terminazione - termina = 1; + status->exiting = 1; break; } } } } + free(status); destroyThreadPool(pool, 0); // notifico che i thread dovranno uscire diff --git a/src/serverWorker.c b/src/serverWorker.c index fa18d59..0e12f57 100644 --- a/src/serverWorker.c +++ b/src/serverWorker.c @@ -6,14 +6,15 @@ #include #include +#include // converte tutti i carattere minuscoli in maiuscoli static void toup(char *str) { char *p = str; - while(*p != '\0') { - *p = (islower(*p)?toupper(*p):*p); + while(*p != '\0') { + *p = (islower(*p)?toupper(*p):*p); ++p; - } + } } // funzione eseguita dal Worker thread del pool @@ -21,41 +22,46 @@ static void toup(char *str) { // void threadF(void *arg) { assert(arg); - long* args = (long*)arg; - long connfd = args[0]; - long* termina = (long*)(args[1]); - free(arg); + + long* connfd = (long*)arg[0]; + serverStatus* status = (serverStatus*)(arg[1]); + fd_set set, tmpset; FD_ZERO(&set); - FD_SET(connfd, &set); - + FD_SET(*connfd, &set); + do { tmpset=set; int r; // ogni tanto controllo se devo terminare struct timeval timeout={0, 100000}; // 100 milliseconds if ((r=select(connfd+1, &tmpset, NULL, NULL, &timeout)) < 0) { - perror("select"); + perror("Select"); break; } if (r==0) { - if (*termina) break; + if ((status->exiting) != 0) + break; continue; } + + + // comunicate with the client msg_t str; - int n; - if ((n=readn(connfd, &str.len, sizeof(int))) == -1) { + long n; + if ((n=readn(connfd, &str.len, sizeof(long))) == -1) { perror("read1"); break; } - - if (n==0) break; - str.str = calloc((str.len), sizeof(char)); + + if (n==0) + break; + str.str = calloc(str.len, sizeof(char)); if (!str.str) { perror("calloc"); fprintf(stderr, "Memoria esaurita....\n"); break; - } + } if ((n=readn(connfd, str.str, str.len * sizeof(char))) == -1) { perror("read2"); free(str.str); @@ -75,6 +81,6 @@ void threadF(void *arg) { break; } free(str.str); - } while(*termina == 0); - close(connfd); + } while(status->exiting == 0); + close(connfd); }