diff --git a/Makefile b/Makefile index 11dc549..fbe227a 100644 --- a/Makefile +++ b/Makefile @@ -154,7 +154,6 @@ test3: all @echo "backlog = 100" >> $(BUILD_DIR)/config.ini $(BUILD_DIR)/server $(BUILD_DIR)/config.ini & bash scripts/test3.sh & - @echo "" @echo "waiting for 30 seconds" @sleep 30 pkill --signal SIGINT -f $(BUILD_DIR)/server diff --git a/lib/api/api.c b/lib/api/api.c index 94ef7c3..0fcc407 100644 --- a/lib/api/api.c +++ b/lib/api/api.c @@ -666,6 +666,15 @@ int writeFile(const char* pathname, const char* dirname) { } } } + freeResponse(res); + free(res); + res = calloc(1, sizeof(response_t)); + if(!res){ + perror("writeFile: calloc"); + free(content); + free(cmd); + return -1; + } /* send file to server */ if (writen(fd_skt, content, size) == -1) { @@ -677,7 +686,6 @@ int writeFile(const char* pathname, const char* dirname) { return -1; } - /* reciveData(, 0) because if we get a MEOK we don't expect files */ if(reciveData(res, 0) < 0) { /* errno is set by reciveData */ diff --git a/lib/threadpool/apiFile.c b/lib/threadpool/apiFile.c index b4a8d1e..37082e4 100644 --- a/lib/threadpool/apiFile.c +++ b/lib/threadpool/apiFile.c @@ -453,7 +453,7 @@ void readNFiles(int num, queueT *q, long fd_c, taglia_t *taglia) { toSend[i]->filepath, toSend[i]->valid); } - n += snprintf(tmp_buf+n, m-n, "readNFile dimensione totale = %ld\n", + n += snprintf(tmp_buf+n, m-n, "readNFile dimensione totale = %ld B\n", tot); sendMessageFileN(MEOK, toSend, ntosend, fd_c, taglia, tmp_buf); diff --git a/lib/threadpool/fileQueue.c b/lib/threadpool/fileQueue.c index 04de0aa..380b9b7 100644 --- a/lib/threadpool/fileQueue.c +++ b/lib/threadpool/fileQueue.c @@ -129,7 +129,7 @@ int enqueue(queueT *q, fileT* data) { goto _end_enqueue; } - /* insert the element */ + /* insert the element at the end */ nodeT *newNode = malloc(sizeof(nodeT)); if (newNode == NULL) { perror("enqueue: malloc"); @@ -178,6 +178,7 @@ fileT* dequeue(queueT *q) { fileT *data = (q->head)->data; + /* dequeue the first in the list */ nodeT *tmp = NULL; tmp = q->head; q->head = (q->head)->next; @@ -217,17 +218,26 @@ fileT ** dequeueN(queueT *q, char *filepath, size_t s) { goto _end_dequeueN; } - if(q->maxSize > s) { + if(q->maxSize < s) { errno = EINVAL; goto _end_dequeueN; } /* try to find the file */ nodeT *tmp = q->head; + /* if LRU keep track of previous */ +#if ALGORITHM == 1 + nodeT *prev = NULL; +#endif + while (tmp) { if (strcmp(filepath, (tmp->data)->filepath) == 0) { /* found */ break; } + /* if LRU keep track of previous */ +#if ALGORITHM == 1 + prev = tmp; +#endif tmp = tmp->next; } @@ -236,39 +246,80 @@ fileT ** dequeueN(queueT *q, char *filepath, size_t s) { goto _end_dequeueN; } - tmp = NULL; + nodeT* file = tmp; + + /* if LRU put the file at the end */ +#if ALGORITHM == 1 + if(prev==NULL && tmp->next==NULL) { + q->head = tmp; + q->tail = tmp; + } else if(prev==NULL) { + q->head = tmp->next; + q->tail->next = tmp; + q->tail = tmp; + tmp->next = NULL; + } else if(tmp->next!=NULL) { + prev->next = tmp->next; + q->tail->next = tmp; + q->tail = tmp; + tmp->next = NULL; + } +#endif /* ALGORITHM == 1 */ + + tmp = q->head; returnList = calloc(1, sizeof(*returnList)); if(!returnList) { perror("dequeueN: calloc"); goto _end_dequeueN; } - returnList[0] = NULL; int purged = 0; + int addFileAtEnd = 0; while(q->size + s > q->maxSize) { - purged++; + if (q->head == NULL) { /* queue becomes empty */ + q->tail = NULL; + break; /* we eliminated everything so we must have enought space */ + } + if(q->head == file) { /* dont delete the file to expand */ + q->head = q->head->next; + addFileAtEnd = 1; + } + + tmp = q->head; + q->head = q->head->next; + + ++purged; returnList = realloc(returnList, purged * sizeof(fileT*)); if(!returnList) { perror("dequeueN: realloc"); goto _end_dequeueN; } - tmp = q->head; - q->head = (q->head)->next; - returnList[purged-1] = tmp->data; --q->len; q->size -= tmp->data->size; - - if (q->head == NULL) { /* queue becomes empty */ - q->tail = NULL; - break; /* we eliminated everything so we must have enought space */ + free(tmp); /* free of the node */ + } + if(addFileAtEnd == 1) { + /* if LRU, we know already that this code is unrechable + * and that q->head must be NULL if rechable */ + if(q->head == NULL) { + q->head = file; + q->head->next = NULL; + } else { + file->next = q->head; + q->head = file; } } + returnList = realloc(returnList, (purged+1) * sizeof(fileT*)); + if(!returnList) { + perror("dequeueN: realloc"); + goto _end_dequeueN; + } returnList[purged] = NULL; /* null terminated */ - tmp->data->size += s; + file->data->size += s; q->size += s; UNLOCK_RETURN(&q->m, NULL); /* end me */ @@ -357,11 +408,19 @@ int lockFileInQueue(queueT *q, char *filepath, int owner) { /* find file */ nodeT *tmp = q->head; + /* if LRU keep track of previous */ +#if ALGORITHM == 1 + nodeT *prev = NULL; +#endif while (tmp) { if (strcmp(filepath, (tmp->data)->filepath) == 0) { /* found */ break; } + /* if LRU keep track of previous */ +#if ALGORITHM == 1 + prev = tmp; +#endif tmp = tmp->next; } @@ -380,6 +439,25 @@ int lockFileInQueue(queueT *q, char *filepath, int owner) { (tmp->data)->O_LOCK = 1; (tmp->data)->owner = owner; + /* if LRU put the file at the end */ +#if ALGORITHM == 1 + if(prev==NULL && tmp->next==NULL) { + q->head = tmp; + q->tail = tmp; + } else if(prev==NULL) { + q->head = tmp->next; + q->tail->next = tmp; + q->tail = tmp; + tmp->next = NULL; + } else if(tmp->next!=NULL) { + prev->next = tmp->next; + q->tail->next = tmp; + q->tail = tmp; + tmp->next = NULL; + } +#endif /* ALGORITHM == 1 */ + + UNLOCK_RETURN(&q->m, -1); /* end me */ return 0; @@ -455,10 +533,19 @@ int openFileInQueue(queueT *q, char *filepath, int O_LOCK, int owner) { /* find the file */ nodeT *tmp = q->head; + /* if LRU keep track of previous */ +#if ALGORITHM == 1 + nodeT *prev = NULL; +#endif + while (tmp) { if (strcmp(filepath, (tmp->data)->filepath) == 0) { /* found */ break; } + /* if LRU keep track of previous */ +#if ALGORITHM == 1 + prev = tmp; +#endif tmp = tmp->next; } @@ -480,6 +567,24 @@ int openFileInQueue(queueT *q, char *filepath, int O_LOCK, int owner) { (tmp->data)->owner = owner; } + /* if LRU put the file at the end */ +#if ALGORITHM == 1 + if(prev==NULL && tmp->next==NULL) { + q->head = tmp; + q->tail = tmp; + } else if(prev==NULL) { + q->head = tmp->next; + q->tail->next = tmp; + q->tail = tmp; + tmp->next = NULL; + } else if(tmp->next!=NULL) { + prev->next = tmp->next; + q->tail->next = tmp; + q->tail = tmp; + tmp->next = NULL; + } +#endif /* ALGORITHM == 1 */ + UNLOCK_RETURN(&q->m, -1); /* end me */ return 0; @@ -551,11 +656,6 @@ int writeFileInQueue(queueT *q, char *filepath, void *data, size_t size, int own goto _end_write_file_queue; } - if (q->size + size > q->maxSize) { /* not enough space */ - errno = EFBIG; - goto _end_write_file_queue; - } - /* find the file */ nodeT *tmp = q->head; while (tmp) { @@ -570,6 +670,11 @@ int writeFileInQueue(queueT *q, char *filepath, void *data, size_t size, int own goto _end_write_file_queue; } + if (q->size - tmp->data->size + size > q->maxSize) { /* not enough space */ + errno = EFBIG; + goto _end_write_file_queue; + } + if ((tmp->data)->open == 0 || ((tmp->data)->O_LOCK && (tmp->data)->owner != owner)) { /* file is closed or the client does not hold the lock */ errno = EPERM; @@ -611,11 +716,6 @@ int appendFileInQueue(queueT *q, char *filepath, void *data, size_t size, int ow goto _end_append_file_queue; } - if (q->size + size > q->maxSize) { /* not enough space */ - errno = EFBIG; - goto _end_append_file_queue; - } - /* find the file */ nodeT *tmp = q->head; while (tmp) { @@ -630,6 +730,11 @@ int appendFileInQueue(queueT *q, char *filepath, void *data, size_t size, int ow goto _end_append_file_queue; } + if (q->size - tmp->data->size + size > q->maxSize) { /* not enough space */ + errno = EFBIG; + goto _end_append_file_queue; + } + if ((tmp->data)->open == 0 || ((tmp->data)->O_LOCK && (tmp->data)->owner != owner)) { /* file is closed or the client does not hold the lock */ errno = EPERM; @@ -738,11 +843,19 @@ fileT* find(queueT *q, char *filepath) { fileT *res = NULL; nodeT *tmp = q->head; + /* if LRU keep track of previous */ +#if ALGORITHM == 1 + nodeT *prev = NULL; +#endif while (tmp) { if (strcmp(filepath, (tmp->data)->filepath) == 0) { /* trovato */ break; } + /* if LRU keep track of previous */ +#if ALGORITHM == 1 + prev = tmp; +#endif tmp = tmp->next; } @@ -763,6 +876,24 @@ fileT* find(queueT *q, char *filepath) { goto _end_find_in_queue; } + /* if LRU put the file at the end */ +#if ALGORITHM == 1 + if(prev==NULL && tmp->next==NULL) { + q->head = tmp; + q->tail = tmp; + } else if(prev==NULL) { + q->head = tmp->next; + q->tail->next = tmp; + q->tail = tmp; + tmp->next = NULL; + } else if(tmp->next!=NULL) { + prev->next = tmp->next; + q->tail->next = tmp; + q->tail = tmp; + tmp->next = NULL; + } +#endif /* ALGORITHM == 1 */ + UNLOCK_RETURN(&q->m, NULL); /* end me */ return res; @@ -812,6 +943,14 @@ fileT ** request(queueT *q, int n) { tmp = tmp->next; } + /* if LRU put the files at the end */ +#if ALGORITHM == 1 + q->tail->next = q->head; + q->head = tmp->next; + tmp->next = NULL; + q->tail = tmp; +#endif /* ALGORITHM == 1 */ + UNLOCK_RETURN(&q->m, NULL); /* end me */ return returnList; @@ -835,17 +974,43 @@ int searchFile(queueT *q, char *filepath) { goto _end_search_file_in_queue; nodeT *tmp = q->head; + /* if LRU keep track of previous */ +#if ALGORITHM == 1 + nodeT *prev = NULL; +#endif while (tmp) { if (strcmp(filepath, (tmp->data)->filepath) == 0) { /* found */ break; } + /* if LRU keep track of previous */ +#if ALGORITHM == 1 + prev = tmp; +#endif tmp = tmp->next; } if(!tmp) goto _end_search_file_in_queue; + /* if LRU put the file at the end */ +#if ALGORITHM == 1 + if(prev==NULL && tmp->next==NULL) { + q->head = tmp; + q->tail = tmp; + } else if(prev==NULL) { + q->head = tmp->next; + q->tail->next = tmp; + q->tail = tmp; + tmp->next = NULL; + } else if(tmp->next!=NULL) { + prev->next = tmp->next; + q->tail->next = tmp; + q->tail = tmp; + tmp->next = NULL; + } +#endif /* ALGORITHM == 1 */ + UNLOCK_RETURN(&q->m, 0); /* end me */ return 1; @@ -897,6 +1062,9 @@ void destroyQueue(queueT *q) { if (errno) { perror("destroyQueue: voidDequeue"); } + if(q->head == NULL) { + break; + } } pthread_mutex_destroy(&q->m); diff --git a/lib/threadpool/fileQueue.h b/lib/threadpool/fileQueue.h index ee1d230..6b65187 100644 --- a/lib/threadpool/fileQueue.h +++ b/lib/threadpool/fileQueue.h @@ -7,6 +7,12 @@ #include "conn.h" +/* Algoritmo che viene usato per il rimpiazzo dei dati: + se = 0 -> FIFO + se = 1 -> LRU + */ +#define ALGORITHM 1 + /* struttura dati per gestire i file in memoria principale */ typedef struct { char *filepath; /* path assoluto del file */ diff --git a/src/client.c b/src/client.c index 4db601d..3a435c9 100644 --- a/src/client.c +++ b/src/client.c @@ -415,7 +415,7 @@ int execute(cmd_t *l, int print) { interval.tv_sec = (num/1000); if (print) - fprintf(stdout, "t - Tempo fra due richieste: %ld ms\tEsito: ok\n", num); + fprintf(stdout, "t - Tempo fra due richieste: %ld ms [Esito: ok]\n", num); tmp = NULL; break; diff --git a/src/server.c b/src/server.c index 6520275..a29047a 100644 --- a/src/server.c +++ b/src/server.c @@ -209,7 +209,7 @@ int main(int argc, char *argv[]) { if( taglia_log(taglia, buf) < 0) goto _cleanup; - printf("File Server ready."); + printf("File Server ready.\n"); fflush(stdout);