2022-04-27 21:18:25 +02:00
|
|
|
#define _POSIX_C_SOURCE 200809L
|
2022-04-09 00:37:56 +02:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <stdio.h>
|
2022-04-27 21:18:25 +02:00
|
|
|
#include <string.h>
|
2022-04-09 00:37:56 +02:00
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
#include "fileQueue.h"
|
|
|
|
|
#include "util.h"
|
2022-03-15 00:30:04 +01:00
|
|
|
|
2022-04-27 21:18:25 +02:00
|
|
|
#define MAXNAMELEN 512
|
2022-03-15 00:30:04 +01:00
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* create a fileT file */
|
|
|
|
|
fileT* createFileT(char *f, int O_LOCK, int client, int open) {
|
2022-03-15 00:30:04 +01:00
|
|
|
if(!f){
|
|
|
|
|
errno = EINVAL;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fileT *file = malloc(sizeof(fileT));
|
|
|
|
|
|
2022-04-08 21:32:52 +02:00
|
|
|
if (file == NULL) {
|
2022-05-07 22:21:20 +02:00
|
|
|
perror("createFileT: malloc");
|
2022-03-15 00:30:04 +01:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-08 21:32:52 +02:00
|
|
|
file->O_LOCK = (O_LOCK == 0)? 0 : 1;
|
|
|
|
|
file->owner = client;
|
|
|
|
|
file->open = (open == 0)? 0 : 1;
|
|
|
|
|
file->size = 0;
|
|
|
|
|
file->valid = 0;
|
2022-03-15 00:30:04 +01:00
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
file->filepath = calloc(strnlen(f, MAXNAMELEN)+1, sizeof(char));
|
|
|
|
|
if (file->filepath == NULL) {
|
|
|
|
|
perror("createFileT: malloc");
|
2022-04-08 21:32:52 +02:00
|
|
|
destroyFile(file);
|
2022-03-15 00:30:04 +01:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-27 21:18:25 +02:00
|
|
|
strncpy(file->filepath, f, strnlen(f, MAXNAMELEN));
|
2022-03-15 00:30:04 +01:00
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* after a realloc is enough */
|
2022-04-29 15:47:27 +02:00
|
|
|
if ((file->data = calloc(1, sizeof(char))) == NULL) {
|
2022-05-07 22:21:20 +02:00
|
|
|
perror("createFileT: calloc");
|
2022-03-15 00:30:04 +01:00
|
|
|
return NULL;
|
|
|
|
|
}
|
2022-04-08 21:32:52 +02:00
|
|
|
return file;
|
2022-03-15 00:30:04 +01:00
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* append on fileT */
|
2022-03-15 00:30:04 +01:00
|
|
|
int writeFileT(fileT *f, void *data, size_t size) {
|
|
|
|
|
if(!f || !data || size < 0){
|
|
|
|
|
errno = EINVAL;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-29 15:47:27 +02:00
|
|
|
if(size == 0) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2022-04-27 21:18:25 +02:00
|
|
|
|
2022-04-04 18:58:40 +02:00
|
|
|
if ((f->data = realloc(f->data, f->valid + size)) == NULL) {
|
2022-05-07 22:21:20 +02:00
|
|
|
perror("writeFileT: realloc");
|
2022-03-15 00:30:04 +01:00
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-04 18:58:40 +02:00
|
|
|
memcpy((char*) f->data + f->valid, data, size);
|
|
|
|
|
f->valid = f->valid + size;
|
|
|
|
|
f->size = (f->valid>f->size)?f->valid:f->size;
|
2022-04-08 21:32:52 +02:00
|
|
|
return 0;
|
2022-03-15 00:30:04 +01:00
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* destroy fileT */
|
2022-03-15 00:30:04 +01:00
|
|
|
void destroyFile(fileT *f) {
|
|
|
|
|
if(!f)
|
|
|
|
|
return;
|
|
|
|
|
if(f->filepath)
|
|
|
|
|
free(f->filepath);
|
|
|
|
|
if(f->data)
|
|
|
|
|
free(f->data);
|
|
|
|
|
free(f);
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
// -----------------------------------------------------------------------------
|
2022-03-15 00:30:04 +01:00
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* create queue */
|
2022-03-15 00:30:04 +01:00
|
|
|
queueT* createQueue(size_t maxLen, size_t maxSize) {
|
|
|
|
|
if(maxLen<0 || maxSize<0){
|
|
|
|
|
errno = EINVAL;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
queueT *q = malloc(sizeof(queueT));
|
|
|
|
|
if(q==NULL){
|
2022-05-07 22:21:20 +02:00
|
|
|
perror("createQueue: malloc");
|
2022-03-15 00:30:04 +01:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* create lock */
|
2022-03-15 00:30:04 +01:00
|
|
|
if (pthread_mutex_init(&q->m, NULL) != 0) {
|
2022-05-07 22:21:20 +02:00
|
|
|
perror("createQueue: pthread_mutex_init");
|
2022-03-15 00:30:04 +01:00
|
|
|
destroyQueue(q);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
q->head = NULL;
|
|
|
|
|
q->tail = NULL;
|
|
|
|
|
q->maxLen = maxLen;
|
|
|
|
|
q->len = 0;
|
|
|
|
|
q->maxSize = maxSize;
|
|
|
|
|
q->size = 0;
|
|
|
|
|
|
|
|
|
|
return q;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* insert into the queue */
|
2022-03-15 00:30:04 +01:00
|
|
|
int enqueue(queueT *q, fileT* data) {
|
|
|
|
|
if(!q || !data){
|
|
|
|
|
errno = EINVAL;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
LOCK_RETURN(&q->m, -1); /* begin me */
|
2022-03-15 00:30:04 +01:00
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
if (q->len == q->maxLen) { /* too many files */
|
2022-03-15 00:30:04 +01:00
|
|
|
errno = ENFILE;
|
|
|
|
|
goto _end_enqueue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (q->size + data->size > q->maxSize) {
|
|
|
|
|
errno = EFBIG;
|
|
|
|
|
goto _end_enqueue;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-19 21:32:44 +02:00
|
|
|
/* insert the element at the end */
|
2022-03-15 00:30:04 +01:00
|
|
|
nodeT *newNode = malloc(sizeof(nodeT));
|
|
|
|
|
if (newNode == NULL) {
|
2022-05-07 22:21:20 +02:00
|
|
|
perror("enqueue: malloc");
|
2022-03-15 00:30:04 +01:00
|
|
|
goto _end_enqueue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
newNode->data = data;
|
|
|
|
|
newNode->next = NULL;
|
2022-04-08 21:32:52 +02:00
|
|
|
nodeT *tmp = q->head;
|
2022-03-15 00:30:04 +01:00
|
|
|
|
|
|
|
|
if (q->head == NULL)
|
|
|
|
|
q->head = newNode;
|
|
|
|
|
else {
|
|
|
|
|
while (tmp->next)
|
2022-04-08 21:32:52 +02:00
|
|
|
tmp = tmp->next;
|
2022-03-15 00:30:04 +01:00
|
|
|
|
2022-04-08 21:32:52 +02:00
|
|
|
tmp->next = newNode;
|
2022-03-15 00:30:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
q->tail = newNode;
|
|
|
|
|
|
|
|
|
|
++q->len;
|
|
|
|
|
q->size += data->size;
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
UNLOCK_RETURN(&q->m, -1); /* end me */
|
2022-03-15 00:30:04 +01:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
_end_enqueue:
|
|
|
|
|
UNLOCK_RETURN(&q->m, -1);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* dequeue one element */
|
2022-03-15 00:30:04 +01:00
|
|
|
fileT* dequeue(queueT *q) {
|
|
|
|
|
if(!q) {
|
|
|
|
|
errno = EINVAL;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
LOCK_RETURN(&q->m, NULL); /* begin me */
|
2022-03-15 00:30:04 +01:00
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
if (q->head == NULL || q->len == 0) { /* empty queue */
|
2022-03-15 00:30:04 +01:00
|
|
|
errno = ENOENT;
|
|
|
|
|
goto _end_dequeue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fileT *data = (q->head)->data;
|
|
|
|
|
|
2022-05-19 21:32:44 +02:00
|
|
|
/* dequeue the first in the list */
|
2022-03-15 00:30:04 +01:00
|
|
|
nodeT *tmp = NULL;
|
|
|
|
|
tmp = q->head;
|
|
|
|
|
q->head = (q->head)->next;
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
if (q->head == NULL) { /* queue becomes empty */
|
2022-03-15 00:30:04 +01:00
|
|
|
q->tail = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
--q->len;
|
|
|
|
|
q->size -= data->size;
|
2022-05-07 22:21:20 +02:00
|
|
|
free(tmp); /* free of the node */
|
2022-03-15 00:30:04 +01:00
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
UNLOCK_RETURN(&q->m, NULL); /* end me */
|
2022-03-15 00:30:04 +01:00
|
|
|
return data;
|
|
|
|
|
|
|
|
|
|
_end_dequeue:
|
|
|
|
|
UNLOCK_RETURN(&q->m, NULL);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* dequeue until we have s free space and expand the file by s */
|
2022-04-04 18:58:40 +02:00
|
|
|
fileT ** dequeueN(queueT *q, char *filepath, size_t s) {
|
|
|
|
|
if(!q) {
|
|
|
|
|
errno = EINVAL;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
if(s<=0) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
LOCK_RETURN(&q->m, NULL); /* begin me */
|
2022-04-04 18:58:40 +02:00
|
|
|
|
2022-05-17 18:41:50 +02:00
|
|
|
fileT **returnList = NULL; /* list of removed files */
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
if (q->head == NULL || q->len == 0) { /* empty queue */
|
2022-04-04 18:58:40 +02:00
|
|
|
errno = ENOENT;
|
|
|
|
|
goto _end_dequeueN;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-19 21:32:44 +02:00
|
|
|
if(q->maxSize < s) {
|
2022-04-04 18:58:40 +02:00
|
|
|
errno = EINVAL;
|
|
|
|
|
goto _end_dequeueN;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* try to find the file */
|
2022-04-04 18:58:40 +02:00
|
|
|
nodeT *tmp = q->head;
|
2022-05-19 21:32:44 +02:00
|
|
|
/* if LRU keep track of previous */
|
|
|
|
|
#if ALGORITHM == 1
|
|
|
|
|
nodeT *prev = NULL;
|
|
|
|
|
#endif
|
|
|
|
|
|
2022-04-04 18:58:40 +02:00
|
|
|
while (tmp) {
|
2022-05-07 22:21:20 +02:00
|
|
|
if (strcmp(filepath, (tmp->data)->filepath) == 0) { /* found */
|
2022-04-04 18:58:40 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2022-05-19 21:32:44 +02:00
|
|
|
/* if LRU keep track of previous */
|
|
|
|
|
#if ALGORITHM == 1
|
|
|
|
|
prev = tmp;
|
|
|
|
|
#endif
|
2022-04-04 18:58:40 +02:00
|
|
|
tmp = tmp->next;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
if(!tmp) { /* not found */
|
2022-04-04 18:58:40 +02:00
|
|
|
errno = ENOENT;
|
|
|
|
|
goto _end_dequeueN;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-19 21:32:44 +02:00
|
|
|
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;
|
2022-04-04 18:58:40 +02:00
|
|
|
|
2022-05-17 18:41:50 +02:00
|
|
|
returnList = calloc(1, sizeof(*returnList));
|
|
|
|
|
if(!returnList) {
|
|
|
|
|
perror("dequeueN: calloc");
|
|
|
|
|
goto _end_dequeueN;
|
|
|
|
|
}
|
2022-04-04 18:58:40 +02:00
|
|
|
|
|
|
|
|
int purged = 0;
|
2022-05-19 21:32:44 +02:00
|
|
|
int addFileAtEnd = 0;
|
2022-04-04 18:58:40 +02:00
|
|
|
while(q->size + s > q->maxSize) {
|
2022-05-19 21:32:44 +02:00
|
|
|
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;
|
2022-04-08 22:09:01 +02:00
|
|
|
returnList = realloc(returnList, purged * sizeof(fileT*));
|
2022-04-04 18:58:40 +02:00
|
|
|
if(!returnList) {
|
2022-05-07 22:21:20 +02:00
|
|
|
perror("dequeueN: realloc");
|
2022-04-04 18:58:40 +02:00
|
|
|
goto _end_dequeueN;
|
|
|
|
|
}
|
|
|
|
|
returnList[purged-1] = tmp->data;
|
|
|
|
|
--q->len;
|
|
|
|
|
q->size -= tmp->data->size;
|
2022-05-19 21:32:44 +02:00
|
|
|
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;
|
2022-04-04 18:58:40 +02:00
|
|
|
}
|
|
|
|
|
}
|
2022-05-19 21:32:44 +02:00
|
|
|
|
2022-05-03 23:14:39 +02:00
|
|
|
returnList = realloc(returnList, (purged+1) * sizeof(fileT*));
|
2022-05-19 21:32:44 +02:00
|
|
|
if(!returnList) {
|
|
|
|
|
perror("dequeueN: realloc");
|
|
|
|
|
goto _end_dequeueN;
|
|
|
|
|
}
|
2022-05-07 22:21:20 +02:00
|
|
|
returnList[purged] = NULL; /* null terminated */
|
2022-04-04 18:58:40 +02:00
|
|
|
|
2022-05-19 21:32:44 +02:00
|
|
|
file->data->size += s;
|
2022-04-08 22:09:01 +02:00
|
|
|
q->size += s;
|
2022-04-04 18:58:40 +02:00
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
UNLOCK_RETURN(&q->m, NULL); /* end me */
|
2022-04-08 22:09:01 +02:00
|
|
|
return returnList;
|
2022-04-04 18:58:40 +02:00
|
|
|
|
|
|
|
|
_end_dequeueN:
|
|
|
|
|
UNLOCK_RETURN(&q->m, NULL);
|
2022-05-17 18:41:50 +02:00
|
|
|
if(returnList)
|
|
|
|
|
free(returnList);
|
2022-04-04 18:58:40 +02:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-15 00:30:04 +01:00
|
|
|
void voidDequeue(queueT *q) {
|
|
|
|
|
if(!q) {
|
|
|
|
|
errno = EINVAL;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
LOCK(&q->m); /* begin me */
|
2022-03-15 00:30:04 +01:00
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
if (q->head == NULL || q->len == 0) { /* empty queue */
|
2022-03-15 00:30:04 +01:00
|
|
|
errno = ENOENT;
|
|
|
|
|
goto _end_void_dequeue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nodeT *tmp = NULL;
|
|
|
|
|
tmp = q->head;
|
|
|
|
|
|
|
|
|
|
q->head = (q->head)->next;
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
if (q->head == NULL) { /* queue becomes empty */
|
2022-03-15 00:30:04 +01:00
|
|
|
q->tail = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
--q->len;
|
2022-04-08 22:09:01 +02:00
|
|
|
q->size -= (tmp->data)->size;
|
2022-03-15 00:30:04 +01:00
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
destroyFile(tmp->data); /* free fileT */
|
|
|
|
|
free(tmp); /* free node */
|
2022-03-15 00:30:04 +01:00
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
UNLOCK(&q->m); /* end me */
|
2022-03-15 00:30:04 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
_end_void_dequeue:
|
2022-04-04 18:58:40 +02:00
|
|
|
UNLOCK(&q->m);
|
|
|
|
|
return;
|
2022-03-15 00:30:04 +01:00
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* print queue */
|
2022-03-15 00:30:04 +01:00
|
|
|
int printQueue(FILE *stream, queueT *q) {
|
|
|
|
|
if(!q || !stream) {
|
|
|
|
|
errno = EINVAL;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
LOCK_RETURN(&q->m, -1); /* begin me */
|
2022-03-15 00:30:04 +01:00
|
|
|
|
|
|
|
|
nodeT *tmp = q->head;
|
|
|
|
|
|
2022-04-27 21:18:25 +02:00
|
|
|
fprintf(stream, "Lista file:\n");
|
|
|
|
|
fprintf(stream, "[Nome File] -> Dimensione in MB\n");
|
2022-04-08 22:09:01 +02:00
|
|
|
while (tmp!=NULL) {
|
2022-05-07 22:21:20 +02:00
|
|
|
float res = ((float)(tmp->data)->size)/1000000; /* in MB */
|
|
|
|
|
// float res = ((float)(tmp->data)->valid)/1000000; /* in MB */
|
2022-04-27 21:18:25 +02:00
|
|
|
fprintf(stream, "[%s] -> %f MB\n", (tmp->data)->filepath, res);
|
2022-04-08 22:09:01 +02:00
|
|
|
tmp = tmp->next;
|
2022-03-15 00:30:04 +01:00
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
UNLOCK_RETURN(&q->m, -1); /* end me */
|
2022-03-15 00:30:04 +01:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* acquire lock */
|
2022-03-15 00:30:04 +01:00
|
|
|
int lockFileInQueue(queueT *q, char *filepath, int owner) {
|
|
|
|
|
if(!q || !filepath) {
|
|
|
|
|
errno = EINVAL;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
LOCK_RETURN(&q->m, -1); /* begin me */
|
2022-03-15 00:30:04 +01:00
|
|
|
|
|
|
|
|
if (q->len == 0) {
|
|
|
|
|
errno = ENOENT;
|
|
|
|
|
goto _end_lock_file_queue;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* find file */
|
2022-03-15 00:30:04 +01:00
|
|
|
nodeT *tmp = q->head;
|
2022-05-19 21:32:44 +02:00
|
|
|
/* if LRU keep track of previous */
|
|
|
|
|
#if ALGORITHM == 1
|
|
|
|
|
nodeT *prev = NULL;
|
|
|
|
|
#endif
|
2022-03-15 00:30:04 +01:00
|
|
|
|
|
|
|
|
while (tmp) {
|
2022-05-07 22:21:20 +02:00
|
|
|
if (strcmp(filepath, (tmp->data)->filepath) == 0) { /* found */
|
2022-03-15 00:30:04 +01:00
|
|
|
break;
|
|
|
|
|
}
|
2022-05-19 21:32:44 +02:00
|
|
|
/* if LRU keep track of previous */
|
|
|
|
|
#if ALGORITHM == 1
|
|
|
|
|
prev = tmp;
|
|
|
|
|
#endif
|
2022-03-15 00:30:04 +01:00
|
|
|
tmp = tmp->next;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
if(!tmp) { /* not found */
|
2022-03-15 00:30:04 +01:00
|
|
|
errno = ENOENT;
|
|
|
|
|
goto _end_lock_file_queue;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* lock already aquired by another client */
|
|
|
|
|
if ((tmp->data)->O_LOCK && (tmp->data)->owner != owner) {
|
2022-03-15 00:30:04 +01:00
|
|
|
errno = EPERM;
|
|
|
|
|
goto _end_lock_file_queue;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* aquire lock on the file */
|
2022-04-08 22:09:01 +02:00
|
|
|
(tmp->data)->O_LOCK = 1;
|
|
|
|
|
(tmp->data)->owner = owner;
|
2022-03-15 00:30:04 +01:00
|
|
|
|
2022-05-19 21:32:44 +02:00
|
|
|
/* 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 */
|
|
|
|
|
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
UNLOCK_RETURN(&q->m, -1); /* end me */
|
2022-03-15 00:30:04 +01:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
_end_lock_file_queue:
|
|
|
|
|
UNLOCK_RETURN(&q->m, -1);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int unlockFileInQueue(queueT *q, char *filepath, int owner) {
|
|
|
|
|
if(!q || !filepath) {
|
|
|
|
|
errno = EINVAL;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
LOCK_RETURN(&q->m, -1); /* begin me */
|
2022-03-15 00:30:04 +01:00
|
|
|
|
|
|
|
|
if (q->len == 0) {
|
|
|
|
|
errno = ENOENT;
|
|
|
|
|
goto _end_unlock_file_queue;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* find the file */
|
2022-03-15 00:30:04 +01:00
|
|
|
nodeT *tmp = q->head;
|
|
|
|
|
|
|
|
|
|
while (tmp) {
|
2022-05-07 22:21:20 +02:00
|
|
|
if (strcmp(filepath, (tmp->data)->filepath) == 0) { /* found */
|
2022-03-15 00:30:04 +01:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
tmp = tmp->next;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
if(!tmp) { /* not found */
|
2022-03-15 00:30:04 +01:00
|
|
|
errno = ENOENT;
|
2022-04-08 22:09:01 +02:00
|
|
|
goto _end_unlock_file_queue;
|
2022-03-15 00:30:04 +01:00
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
if((tmp->data)->O_LOCK == 0) { /* no one has the lock */
|
2022-03-15 00:30:04 +01:00
|
|
|
UNLOCK_RETURN(&q->m, -1);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* another client holds the lock */
|
|
|
|
|
if((tmp->data)->O_LOCK == 1 && (tmp->data)->owner != owner) {
|
2022-03-15 00:30:04 +01:00
|
|
|
errno = EPERM;
|
|
|
|
|
goto _end_unlock_file_queue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
(tmp->data)->O_LOCK = 0;
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
UNLOCK_RETURN(&q->m, -1); /* end me */
|
2022-03-15 00:30:04 +01:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
_end_unlock_file_queue:
|
|
|
|
|
UNLOCK_RETURN(&q->m, -1);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* open file */
|
2022-03-15 00:30:04 +01:00
|
|
|
int openFileInQueue(queueT *q, char *filepath, int O_LOCK, int owner) {
|
|
|
|
|
if(!q || !filepath) {
|
|
|
|
|
errno = EINVAL;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
LOCK_RETURN(&q->m, -1); /* begin me */
|
2022-03-15 00:30:04 +01:00
|
|
|
|
|
|
|
|
if (q->len == 0) {
|
|
|
|
|
errno = ENOENT;
|
|
|
|
|
goto _end_open_file_queue;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* find the file */
|
2022-03-15 00:30:04 +01:00
|
|
|
nodeT *tmp = q->head;
|
2022-05-19 21:32:44 +02:00
|
|
|
/* if LRU keep track of previous */
|
|
|
|
|
#if ALGORITHM == 1
|
|
|
|
|
nodeT *prev = NULL;
|
|
|
|
|
#endif
|
|
|
|
|
|
2022-03-15 00:30:04 +01:00
|
|
|
while (tmp) {
|
2022-05-07 22:21:20 +02:00
|
|
|
if (strcmp(filepath, (tmp->data)->filepath) == 0) { /* found */
|
2022-03-15 00:30:04 +01:00
|
|
|
break;
|
|
|
|
|
}
|
2022-05-19 21:32:44 +02:00
|
|
|
/* if LRU keep track of previous */
|
|
|
|
|
#if ALGORITHM == 1
|
|
|
|
|
prev = tmp;
|
|
|
|
|
#endif
|
2022-03-15 00:30:04 +01:00
|
|
|
tmp = tmp->next;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
if(!tmp) { /* not found */
|
2022-03-15 00:30:04 +01:00
|
|
|
errno = ENOENT;
|
|
|
|
|
goto _end_open_file_queue;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* lock aquired by another client */
|
2022-04-09 01:11:46 +02:00
|
|
|
if((tmp->data)->O_LOCK == 1 && (tmp->data)->owner != owner) {
|
2022-03-15 00:30:04 +01:00
|
|
|
errno = EPERM;
|
|
|
|
|
goto _end_open_file_queue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
(tmp->data)->open = 1;
|
|
|
|
|
(tmp->data)->O_LOCK = (O_LOCK==0)?0:1;
|
|
|
|
|
|
|
|
|
|
if(O_LOCK!=0) {
|
2022-04-08 22:09:01 +02:00
|
|
|
(tmp->data)->owner = owner;
|
2022-03-15 00:30:04 +01:00
|
|
|
}
|
|
|
|
|
|
2022-05-19 21:32:44 +02:00
|
|
|
/* 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 */
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
UNLOCK_RETURN(&q->m, -1); /* end me */
|
2022-03-15 00:30:04 +01:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
_end_open_file_queue:
|
|
|
|
|
UNLOCK_RETURN(&q->m, -1);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* close and relese lock */
|
2022-03-15 00:30:04 +01:00
|
|
|
int closeFileInQueue(queueT *q, char *filepath, int owner) {
|
|
|
|
|
if(!q || !filepath) {
|
|
|
|
|
errno = EINVAL;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
LOCK_RETURN(&q->m, -1); /* begin me */
|
2022-03-15 00:30:04 +01:00
|
|
|
|
|
|
|
|
if (q->len == 0) {
|
|
|
|
|
errno = ENOENT;
|
|
|
|
|
goto _end_close_file_queue;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* find file */
|
2022-03-15 00:30:04 +01:00
|
|
|
nodeT *tmp = q->head;
|
|
|
|
|
while (tmp) {
|
2022-05-07 22:21:20 +02:00
|
|
|
if (strcmp(filepath, (tmp->data)->filepath) == 0) { /* found */
|
2022-03-15 00:30:04 +01:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
tmp = tmp->next;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
if(!tmp) { /* not found */
|
2022-03-15 00:30:04 +01:00
|
|
|
errno = ENOENT;
|
|
|
|
|
goto _end_close_file_queue;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* lock aquired by another client */
|
|
|
|
|
if((tmp->data)->O_LOCK == 1 && (tmp->data)->owner != owner) {
|
2022-03-15 00:30:04 +01:00
|
|
|
errno = EPERM;
|
|
|
|
|
goto _end_close_file_queue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
(tmp->data)->open = 0;
|
|
|
|
|
(tmp->data)->O_LOCK = 0;
|
|
|
|
|
(tmp->data)->owner = owner;
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
UNLOCK_RETURN(&q->m, -1); /* end me */
|
2022-03-15 00:30:04 +01:00
|
|
|
return 0;
|
|
|
|
|
|
2022-04-08 22:09:01 +02:00
|
|
|
_end_close_file_queue:
|
2022-03-15 00:30:04 +01:00
|
|
|
UNLOCK_RETURN(&q->m, -1);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int writeFileInQueue(queueT *q, char *filepath, void *data, size_t size, int owner) {
|
|
|
|
|
if(!q || !filepath || !data) {
|
|
|
|
|
errno = EINVAL;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(size == 0)
|
|
|
|
|
return 0;
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
LOCK_RETURN(&q->m, -1); /* begin me */
|
2022-03-15 00:30:04 +01:00
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
if (q->len == 0) { /* empty queue */
|
2022-03-15 00:30:04 +01:00
|
|
|
errno = ENOENT;
|
|
|
|
|
goto _end_write_file_queue;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* find the file */
|
2022-03-15 00:30:04 +01:00
|
|
|
nodeT *tmp = q->head;
|
|
|
|
|
while (tmp) {
|
2022-05-07 22:21:20 +02:00
|
|
|
if (strcmp(filepath, (tmp->data)->filepath) == 0) { /* found */
|
2022-03-15 00:30:04 +01:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
tmp = tmp->next;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
if(!tmp) { /* not found */
|
2022-03-15 00:30:04 +01:00
|
|
|
errno = ENOENT;
|
|
|
|
|
goto _end_write_file_queue;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-19 21:32:44 +02:00
|
|
|
if (q->size - tmp->data->size + size > q->maxSize) { /* not enough space */
|
|
|
|
|
errno = EFBIG;
|
|
|
|
|
goto _end_write_file_queue;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-15 00:30:04 +01:00
|
|
|
if ((tmp->data)->open == 0 || ((tmp->data)->O_LOCK && (tmp->data)->owner != owner)) {
|
2022-05-07 22:21:20 +02:00
|
|
|
/* file is closed or the client does not hold the lock */
|
2022-03-15 00:30:04 +01:00
|
|
|
errno = EPERM;
|
|
|
|
|
goto _end_write_file_queue;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* write */
|
2022-04-04 18:58:40 +02:00
|
|
|
if (((tmp->data)->data = realloc((tmp->data)->data, size)) == NULL) {
|
2022-05-07 22:21:20 +02:00
|
|
|
perror("writeFileInQueue: realloc");
|
2022-03-15 00:30:04 +01:00
|
|
|
goto _end_write_file_queue;
|
|
|
|
|
}
|
|
|
|
|
memcpy((tmp->data)->data, data, size);
|
|
|
|
|
|
|
|
|
|
q->size = (q->size) - ((tmp->data)->size) + size;
|
2022-04-04 18:58:40 +02:00
|
|
|
(tmp->data)->valid = size;
|
2022-03-15 00:30:04 +01:00
|
|
|
(tmp->data)->size = size;
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
UNLOCK_RETURN(&q->m, -1); /* end me */
|
2022-03-15 00:30:04 +01:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
_end_write_file_queue:
|
|
|
|
|
UNLOCK_RETURN(&q->m, -1);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int appendFileInQueue(queueT *q, char *filepath, void *data, size_t size, int owner) {
|
|
|
|
|
if (!q || !filepath || !data) {
|
|
|
|
|
errno = EINVAL;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
if (size == 0)
|
|
|
|
|
return 0;
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
LOCK_RETURN(&q->m, -1); /* begin me */
|
2022-03-15 00:30:04 +01:00
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
if (q->len == 0) { /* empty queue */
|
2022-03-15 00:30:04 +01:00
|
|
|
errno = ENOENT;
|
|
|
|
|
goto _end_append_file_queue;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* find the file */
|
2022-03-15 00:30:04 +01:00
|
|
|
nodeT *tmp = q->head;
|
|
|
|
|
while (tmp) {
|
2022-05-07 22:21:20 +02:00
|
|
|
if (strcmp(filepath, (tmp->data)->filepath) == 0) { /* found */
|
2022-03-15 00:30:04 +01:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
tmp = tmp->next;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
if(!tmp) { /* not found */
|
2022-03-15 00:30:04 +01:00
|
|
|
errno = ENOENT;
|
|
|
|
|
goto _end_append_file_queue;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-19 21:32:44 +02:00
|
|
|
if (q->size - tmp->data->size + size > q->maxSize) { /* not enough space */
|
|
|
|
|
errno = EFBIG;
|
|
|
|
|
goto _end_append_file_queue;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-15 00:30:04 +01:00
|
|
|
if ((tmp->data)->open == 0 || ((tmp->data)->O_LOCK && (tmp->data)->owner != owner)) {
|
2022-05-07 22:21:20 +02:00
|
|
|
/* file is closed or the client does not hold the lock */
|
2022-03-15 00:30:04 +01:00
|
|
|
errno = EPERM;
|
|
|
|
|
goto _end_append_file_queue;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* write */
|
2022-04-04 18:58:40 +02:00
|
|
|
if (((tmp->data)->data = realloc((tmp->data)->data, (tmp->data)->valid + size)) == NULL) {
|
2022-05-07 22:21:20 +02:00
|
|
|
perror("appendFileInQueue: realloc");
|
2022-03-15 00:30:04 +01:00
|
|
|
goto _end_append_file_queue;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-08 22:09:01 +02:00
|
|
|
memcpy(((char *)(tmp->data)->data) + (tmp->data)->valid, data, size);
|
2022-05-07 22:21:20 +02:00
|
|
|
/* memmove could be an alternative */
|
2022-04-04 18:58:40 +02:00
|
|
|
(tmp->data)->valid += size;
|
|
|
|
|
q->size -= (tmp->data)->size;
|
|
|
|
|
(tmp->data)->size = ((tmp->data)->size > (tmp->data)->valid) ? (tmp->data)->size : (tmp->data)->valid;
|
|
|
|
|
q->size += (tmp->data)->size;
|
2022-03-15 00:30:04 +01:00
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
UNLOCK_RETURN(&q->m, -1); /* end me */
|
2022-03-15 00:30:04 +01:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
_end_append_file_queue:
|
|
|
|
|
UNLOCK_RETURN(&q->m, -1);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int removeFileFromQueue(queueT *q, char *filepath, int owner) {
|
|
|
|
|
if(!q || !filepath) {
|
|
|
|
|
errno = EINVAL;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
LOCK_RETURN(&q->m, -1); /* begin me */
|
2022-03-15 00:30:04 +01:00
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
if (q->len == 0) { /* empty queue */
|
2022-03-15 00:30:04 +01:00
|
|
|
errno = ENOENT;
|
|
|
|
|
goto _end_remove_file_queue;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* find the file */
|
2022-03-15 00:30:04 +01:00
|
|
|
nodeT *tmp = q->head;
|
|
|
|
|
nodeT *pre = q->head;
|
|
|
|
|
while (tmp) {
|
2022-05-07 22:21:20 +02:00
|
|
|
if (strcmp(filepath, (tmp->data)->filepath) == 0) { /* found */
|
2022-03-15 00:30:04 +01:00
|
|
|
break;
|
|
|
|
|
}
|
2022-04-08 22:09:01 +02:00
|
|
|
if(pre!=tmp)
|
|
|
|
|
pre = pre->next;
|
2022-03-15 00:30:04 +01:00
|
|
|
tmp = tmp->next;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
if (!tmp) { /* not found */
|
2022-03-15 00:30:04 +01:00
|
|
|
errno = ENOENT;
|
|
|
|
|
goto _end_remove_file_queue;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-30 00:37:59 +02:00
|
|
|
if (((tmp->data)->O_LOCK) && ((tmp->data)->owner != owner)) {
|
2022-05-07 22:21:20 +02:00
|
|
|
/* lock not by the client */
|
2022-03-15 00:30:04 +01:00
|
|
|
errno = EPERM;
|
2022-04-08 22:09:01 +02:00
|
|
|
goto _end_remove_file_queue;
|
2022-03-15 00:30:04 +01:00
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
if (tmp == pre) { /* file is the first */
|
2022-03-15 00:30:04 +01:00
|
|
|
q->head = tmp->next;
|
|
|
|
|
|
|
|
|
|
if (tmp->next == NULL) {
|
|
|
|
|
q->tail = tmp;
|
|
|
|
|
}
|
2022-05-07 22:21:20 +02:00
|
|
|
} else {
|
2022-04-08 22:09:01 +02:00
|
|
|
pre->next = tmp->next;
|
2022-03-15 00:30:04 +01:00
|
|
|
|
2022-04-08 22:09:01 +02:00
|
|
|
if (pre->next == NULL) {
|
|
|
|
|
q->tail = pre;
|
2022-03-15 00:30:04 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
--q->len;
|
|
|
|
|
q->size -= (tmp->data)->size;
|
2022-05-07 22:21:20 +02:00
|
|
|
destroyFile(tmp->data); /* free file */
|
|
|
|
|
free(tmp); /* free node */
|
2022-03-15 00:30:04 +01:00
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
UNLOCK_RETURN(&q->m, -1); /* end me */
|
2022-03-15 00:30:04 +01:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
_end_remove_file_queue:
|
|
|
|
|
UNLOCK_RETURN(&q->m, -1);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
// -----------------------------------------------------------------------------
|
2022-03-15 00:30:04 +01:00
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* search for file and return a copy */
|
2022-03-15 00:30:04 +01:00
|
|
|
fileT* find(queueT *q, char *filepath) {
|
|
|
|
|
if(!q || !filepath) {
|
|
|
|
|
errno = EINVAL;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
LOCK_RETURN(&q->m, NULL); /* begin me */
|
2022-03-15 00:30:04 +01:00
|
|
|
|
|
|
|
|
if (q->len == 0)
|
|
|
|
|
goto _end_find_in_queue;
|
|
|
|
|
|
|
|
|
|
fileT *res = NULL;
|
|
|
|
|
nodeT *tmp = q->head;
|
2022-05-19 21:32:44 +02:00
|
|
|
/* if LRU keep track of previous */
|
|
|
|
|
#if ALGORITHM == 1
|
|
|
|
|
nodeT *prev = NULL;
|
|
|
|
|
#endif
|
2022-03-15 00:30:04 +01:00
|
|
|
|
|
|
|
|
while (tmp) {
|
2022-05-07 22:21:20 +02:00
|
|
|
if (strcmp(filepath, (tmp->data)->filepath) == 0) { /* trovato */
|
2022-03-15 00:30:04 +01:00
|
|
|
break;
|
|
|
|
|
}
|
2022-05-19 21:32:44 +02:00
|
|
|
/* if LRU keep track of previous */
|
|
|
|
|
#if ALGORITHM == 1
|
|
|
|
|
prev = tmp;
|
|
|
|
|
#endif
|
2022-03-15 00:30:04 +01:00
|
|
|
tmp = tmp->next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!tmp)
|
|
|
|
|
goto _end_find_in_queue;
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* create a new instance */
|
2022-03-15 00:30:04 +01:00
|
|
|
res = createFileT((tmp->data)->filepath, (tmp->data)->O_LOCK, (tmp->data)->owner, (tmp->data)->open);
|
|
|
|
|
|
|
|
|
|
if (!res) {
|
2022-05-07 22:21:20 +02:00
|
|
|
perror("find: createFileT");
|
2022-03-15 00:30:04 +01:00
|
|
|
goto _end_find_in_queue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (writeFileT(res, (tmp->data)->data, (tmp->data)->size) == -1) {
|
2022-05-07 22:21:20 +02:00
|
|
|
perror("find: writeFileT");
|
2022-04-25 20:24:55 +02:00
|
|
|
destroyFile(res);
|
2022-03-15 00:30:04 +01:00
|
|
|
goto _end_find_in_queue;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-19 21:32:44 +02:00
|
|
|
/* 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 */
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
UNLOCK_RETURN(&q->m, NULL); /* end me */
|
2022-03-15 00:30:04 +01:00
|
|
|
return res;
|
|
|
|
|
|
|
|
|
|
_end_find_in_queue:
|
|
|
|
|
UNLOCK_RETURN(&q->m, NULL);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-17 18:41:50 +02:00
|
|
|
/* 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; i<n; ++i) {
|
|
|
|
|
if(tmp == NULL) {
|
|
|
|
|
errno = ENOENT;
|
|
|
|
|
goto _end_request;
|
|
|
|
|
}
|
|
|
|
|
returnList[i] = tmp->data;
|
|
|
|
|
tmp = tmp->next;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-19 21:32:44 +02:00
|
|
|
/* 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 */
|
|
|
|
|
|
2022-05-17 18:41:50 +02:00
|
|
|
UNLOCK_RETURN(&q->m, NULL); /* end me */
|
|
|
|
|
return returnList;
|
|
|
|
|
|
|
|
|
|
_end_request:
|
|
|
|
|
UNLOCK_RETURN(&q->m, NULL);
|
|
|
|
|
if(returnList)
|
|
|
|
|
free(returnList);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* search for file and return result of search */
|
2022-03-31 22:26:44 +02:00
|
|
|
int searchFile(queueT *q, char *filepath) {
|
|
|
|
|
if(!q || !filepath) {
|
|
|
|
|
errno = EINVAL;
|
2022-04-08 22:09:01 +02:00
|
|
|
return 0;
|
2022-03-31 22:26:44 +02:00
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
LOCK_RETURN(&q->m, 0); /* begin me */
|
2022-03-31 22:26:44 +02:00
|
|
|
|
|
|
|
|
if (q->len == 0)
|
|
|
|
|
goto _end_search_file_in_queue;
|
|
|
|
|
|
|
|
|
|
nodeT *tmp = q->head;
|
2022-05-19 21:32:44 +02:00
|
|
|
/* if LRU keep track of previous */
|
|
|
|
|
#if ALGORITHM == 1
|
|
|
|
|
nodeT *prev = NULL;
|
|
|
|
|
#endif
|
2022-03-31 22:26:44 +02:00
|
|
|
|
|
|
|
|
while (tmp) {
|
2022-05-07 22:21:20 +02:00
|
|
|
if (strcmp(filepath, (tmp->data)->filepath) == 0) { /* found */
|
2022-03-31 22:26:44 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2022-05-19 21:32:44 +02:00
|
|
|
/* if LRU keep track of previous */
|
|
|
|
|
#if ALGORITHM == 1
|
|
|
|
|
prev = tmp;
|
|
|
|
|
#endif
|
2022-03-31 22:26:44 +02:00
|
|
|
tmp = tmp->next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!tmp)
|
|
|
|
|
goto _end_search_file_in_queue;
|
|
|
|
|
|
2022-05-19 21:32:44 +02:00
|
|
|
/* 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 */
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
UNLOCK_RETURN(&q->m, 0); /* end me */
|
2022-03-31 22:26:44 +02:00
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
_end_search_file_in_queue:
|
2022-04-08 22:09:01 +02:00
|
|
|
UNLOCK_RETURN(&q->m, 0);
|
2022-03-31 22:26:44 +02:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* number of elements in queue */
|
2022-03-15 00:30:04 +01:00
|
|
|
size_t getLen(queueT *q) {
|
|
|
|
|
if(!q) {
|
|
|
|
|
errno = EINVAL;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
size_t len = -1;
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
LOCK_RETURN(&q->m, -1); /* begin me */
|
2022-03-15 00:30:04 +01:00
|
|
|
|
2022-04-08 22:09:01 +02:00
|
|
|
len = q->len;
|
2022-03-15 00:30:04 +01:00
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
UNLOCK_RETURN(&q->m, -1); /* end me */
|
2022-03-15 00:30:04 +01:00
|
|
|
return len;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* size in bytes of queue */
|
2022-03-15 00:30:04 +01:00
|
|
|
size_t getSize(queueT *q) {
|
|
|
|
|
if(!q) {
|
|
|
|
|
errno = EINVAL;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
size_t size = -1;
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
LOCK_RETURN(&q->m, -1); /* begin me */
|
2022-03-15 00:30:04 +01:00
|
|
|
|
|
|
|
|
size = q->size;
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
UNLOCK_RETURN(&q->m, -1); /* end me */
|
2022-03-15 00:30:04 +01:00
|
|
|
return size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void destroyQueue(queueT *q) {
|
|
|
|
|
if(!q)
|
|
|
|
|
return;
|
|
|
|
|
|
2022-05-07 22:21:20 +02:00
|
|
|
/* no need for lock over queue */
|
2022-03-15 00:30:04 +01:00
|
|
|
while (q->len > 0) {
|
|
|
|
|
errno = 0;
|
2022-04-08 22:09:01 +02:00
|
|
|
voidDequeue(q);
|
2022-03-15 00:30:04 +01:00
|
|
|
if (errno) {
|
2022-05-07 22:21:20 +02:00
|
|
|
perror("destroyQueue: voidDequeue");
|
2022-03-15 00:30:04 +01:00
|
|
|
}
|
2022-05-19 21:32:44 +02:00
|
|
|
if(q->head == NULL) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
2022-03-15 00:30:04 +01:00
|
|
|
}
|
|
|
|
|
|
2022-04-08 22:09:01 +02:00
|
|
|
pthread_mutex_destroy(&q->m);
|
2022-03-15 00:30:04 +01:00
|
|
|
|
2022-04-08 22:09:01 +02:00
|
|
|
free(q);
|
2022-03-15 00:30:04 +01:00
|
|
|
}
|