diff --git a/lib/threadpool/apiFile.c b/lib/threadpool/apiFile.c index b79d9ac..312d01a 100644 --- a/lib/threadpool/apiFile.c +++ b/lib/threadpool/apiFile.c @@ -417,32 +417,33 @@ void readNFiles(int num, queueT *q, long fd_c, taglia_t *taglia) { int oldNum = num; int64_t ntosend = (num<=0 || num>getLen(q))? getLen(q) : num; - fileT **toSend = calloc(ntosend, sizeof(fileT *)); + fileT **toSend = NULL; n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una readNFile (n = %d) e' terminata con successo. File inviati:\n", fd_c, num); - /* extract n files, we dont check if the client can actually modify - * the files since we add them back immediatly */ + /* extract n files, but dont actually dequeue them */ + toSend = request(q, (int) ntosend); + if(toSend == NULL) { + n = 0; + n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una readNFiles (n = %d) e' terminato con errore del server\n", + fd_c, + oldNum); + perror("readNFiles: request"); + serror(MESE, fd_c, taglia, tmp_buf); + return; + } + size_t tot = 0; for(int i=0;im, NULL); /* begin me */ + fileT **returnList = NULL; /* list of removed files */ + if (q->head == NULL || q->len == 0) { /* empty queue */ errno = ENOENT; goto _end_dequeueN; @@ -235,10 +236,13 @@ fileT ** dequeueN(queueT *q, char *filepath, size_t s) { goto _end_dequeueN; } - fileT **returnList = NULL; /* list of removed files */ tmp = NULL; - returnList = calloc(1, sizeof(fileT*)); + returnList = calloc(1, sizeof(*returnList)); + if(!returnList) { + perror("dequeueN: calloc"); + goto _end_dequeueN; + } returnList[0] = NULL; int purged = 0; @@ -272,6 +276,8 @@ fileT ** dequeueN(queueT *q, char *filepath, size_t s) { _end_dequeueN: UNLOCK_RETURN(&q->m, NULL); + if(returnList) + free(returnList); return NULL; } @@ -765,6 +771,57 @@ _end_find_in_queue: return NULL; } +/* return n files */ +fileT ** request(queueT *q, int n) { + if(!q) { + errno = EINVAL; + return NULL; + } + if(n<=0) { + return NULL; + } + + LOCK_RETURN(&q->m, NULL); /* begin me */ + + fileT **returnList = NULL; /* list of requested files */ + + if (q->head == NULL || q->len == 0) { /* empty queue */ + errno = ENOENT; + goto _end_request; + } + + if(q->size < n) { + errno = EINVAL; + goto _end_request; + } + + returnList = calloc(n+1, sizeof(*returnList)); + if(!returnList) { + perror("dequeueN: calloc"); + goto _end_request; + } + returnList[n] = NULL; + + nodeT *tmp = q->head; + for(int i=0; idata; + tmp = tmp->next; + } + + UNLOCK_RETURN(&q->m, NULL); /* end me */ + return returnList; + +_end_request: + UNLOCK_RETURN(&q->m, NULL); + if(returnList) + free(returnList); + return NULL; +} + /* search for file and return result of search */ int searchFile(queueT *q, char *filepath) { if(!q || !filepath) { diff --git a/lib/threadpool/fileQueue.h b/lib/threadpool/fileQueue.h index b92affe..ee1d230 100644 --- a/lib/threadpool/fileQueue.h +++ b/lib/threadpool/fileQueue.h @@ -67,8 +67,7 @@ void destroyFile(fileT *f); /** - * Alloca ed inizializza una coda di fileT. Deve essere chiamata da un solo - * thread. + * Alloca ed inizializza una coda di fileT. * @param maxLen lunghezza massima della coda * @param maxSize dimensione massima della coda in bytes * @@ -215,6 +214,15 @@ int removeFileFromQueue(queueT *q, char *filepath, int owner); */ fileT* find(queueT *q, char *filepath); +/** + * Estrae n fileT dalla coda senza eliminarli + * @param q puntatore alla coda + * @param n numero di file da estrarre + * + * @return puntatore i file estratti (NULL terminated), NULL se errore + */ +fileT ** request(queueT *q, int n); + /** * Cerca il fileT nella coda e ritorna il siultato dell'operazione * @param q puntatore alla coda sulla quale cercare il fileT