style and comments for fileQueue.*
This commit is contained in:
@ -3,13 +3,13 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <fileQueue.h>
|
#include "fileQueue.h"
|
||||||
#include <util.h>
|
#include "util.h"
|
||||||
|
|
||||||
#define MAXNAMELEN 512
|
#define MAXNAMELEN 512
|
||||||
|
|
||||||
// creazione di un fileT
|
/* create a fileT file */
|
||||||
fileT* createFileT(char *f, int O_LOCK, int client, int open){
|
fileT* createFileT(char *f, int O_LOCK, int client, int open) {
|
||||||
if(!f){
|
if(!f){
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -18,7 +18,7 @@ fileT* createFileT(char *f, int O_LOCK, int client, int open){
|
|||||||
fileT *file = malloc(sizeof(fileT));
|
fileT *file = malloc(sizeof(fileT));
|
||||||
|
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
perror("Malloc createFileT");
|
perror("createFileT: malloc");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,23 +28,24 @@ fileT* createFileT(char *f, int O_LOCK, int client, int open){
|
|||||||
file->size = 0;
|
file->size = 0;
|
||||||
file->valid = 0;
|
file->valid = 0;
|
||||||
|
|
||||||
if ((file->filepath = calloc(strnlen(f, MAXNAMELEN)+1, sizeof(char))) == NULL) {
|
file->filepath = calloc(strnlen(f, MAXNAMELEN)+1, sizeof(char));
|
||||||
perror("Malloc filepath");
|
if (file->filepath == NULL) {
|
||||||
|
perror("createFileT: malloc");
|
||||||
destroyFile(file);
|
destroyFile(file);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy(file->filepath, f, strnlen(f, MAXNAMELEN));
|
strncpy(file->filepath, f, strnlen(f, MAXNAMELEN));
|
||||||
|
|
||||||
// in seguito semplicemente facciamo realloc
|
/* after a realloc is enough */
|
||||||
if ((file->data = calloc(1, sizeof(char))) == NULL) {
|
if ((file->data = calloc(1, sizeof(char))) == NULL) {
|
||||||
perror("Calloc content");
|
perror("createFileT: calloc");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
// append su fileT
|
/* append on fileT */
|
||||||
int writeFileT(fileT *f, void *data, size_t size) {
|
int writeFileT(fileT *f, void *data, size_t size) {
|
||||||
if(!f || !data || size < 0){
|
if(!f || !data || size < 0){
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
@ -56,7 +57,7 @@ int writeFileT(fileT *f, void *data, size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((f->data = realloc(f->data, f->valid + size)) == NULL) {
|
if ((f->data = realloc(f->data, f->valid + size)) == NULL) {
|
||||||
perror("Realloc content");
|
perror("writeFileT: realloc");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +67,7 @@ int writeFileT(fileT *f, void *data, size_t size) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// destroy fileT
|
/* destroy fileT */
|
||||||
void destroyFile(fileT *f) {
|
void destroyFile(fileT *f) {
|
||||||
if(!f)
|
if(!f)
|
||||||
return;
|
return;
|
||||||
@ -77,9 +78,9 @@ void destroyFile(fileT *f) {
|
|||||||
free(f);
|
free(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
// creazione queue
|
/* create queue */
|
||||||
queueT* createQueue(size_t maxLen, size_t maxSize) {
|
queueT* createQueue(size_t maxLen, size_t maxSize) {
|
||||||
if(maxLen<0 || maxSize<0){
|
if(maxLen<0 || maxSize<0){
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
@ -88,13 +89,13 @@ queueT* createQueue(size_t maxLen, size_t maxSize) {
|
|||||||
|
|
||||||
queueT *q = malloc(sizeof(queueT));
|
queueT *q = malloc(sizeof(queueT));
|
||||||
if(q==NULL){
|
if(q==NULL){
|
||||||
perror("Malloc createQueue");
|
perror("createQueue: malloc");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// creazione lock
|
/* create lock */
|
||||||
if (pthread_mutex_init(&q->m, NULL) != 0) {
|
if (pthread_mutex_init(&q->m, NULL) != 0) {
|
||||||
perror("pthread_mutex_init createQueue");
|
perror("createQueue: pthread_mutex_init");
|
||||||
destroyQueue(q);
|
destroyQueue(q);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -109,16 +110,16 @@ queueT* createQueue(size_t maxLen, size_t maxSize) {
|
|||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert
|
/* insert into the queue */
|
||||||
int enqueue(queueT *q, fileT* data) {
|
int enqueue(queueT *q, fileT* data) {
|
||||||
if(!q || !data){
|
if(!q || !data){
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCK_RETURN(&q->m, -1); // begin me
|
LOCK_RETURN(&q->m, -1); /* begin me */
|
||||||
|
|
||||||
if (q->len == q->maxLen) { // too many files
|
if (q->len == q->maxLen) { /* too many files */
|
||||||
errno = ENFILE;
|
errno = ENFILE;
|
||||||
goto _end_enqueue;
|
goto _end_enqueue;
|
||||||
}
|
}
|
||||||
@ -128,10 +129,10 @@ int enqueue(queueT *q, fileT* data) {
|
|||||||
goto _end_enqueue;
|
goto _end_enqueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// inserisco l'elemento
|
/* insert the element */
|
||||||
nodeT *newNode = malloc(sizeof(nodeT));
|
nodeT *newNode = malloc(sizeof(nodeT));
|
||||||
if (newNode == NULL) {
|
if (newNode == NULL) {
|
||||||
perror("malloc newNode");
|
perror("enqueue: malloc");
|
||||||
goto _end_enqueue;
|
goto _end_enqueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,7 +154,7 @@ int enqueue(queueT *q, fileT* data) {
|
|||||||
++q->len;
|
++q->len;
|
||||||
q->size += data->size;
|
q->size += data->size;
|
||||||
|
|
||||||
UNLOCK_RETURN(&q->m, -1); // end me
|
UNLOCK_RETURN(&q->m, -1); /* end me */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
_end_enqueue:
|
_end_enqueue:
|
||||||
@ -161,18 +162,16 @@ _end_enqueue:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove
|
/* dequeue one element */
|
||||||
fileT* dequeue(queueT *q) {
|
fileT* dequeue(queueT *q) {
|
||||||
if(!q) {
|
if(!q) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCK_RETURN(&q->m, NULL); // begin me
|
LOCK_RETURN(&q->m, NULL); /* begin me */
|
||||||
|
|
||||||
// TODO: altri oltre fifo
|
if (q->head == NULL || q->len == 0) { /* empty queue */
|
||||||
|
|
||||||
if (q->head == NULL || q->len == 0) { // coda vuota
|
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
goto _end_dequeue;
|
goto _end_dequeue;
|
||||||
}
|
}
|
||||||
@ -183,15 +182,15 @@ fileT* dequeue(queueT *q) {
|
|||||||
tmp = q->head;
|
tmp = q->head;
|
||||||
q->head = (q->head)->next;
|
q->head = (q->head)->next;
|
||||||
|
|
||||||
if (q->head == NULL) { // coda diventa vuota
|
if (q->head == NULL) { /* queue becomes empty */
|
||||||
q->tail = NULL;
|
q->tail = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
--q->len;
|
--q->len;
|
||||||
q->size -= data->size;
|
q->size -= data->size;
|
||||||
free(tmp); // free del nodo
|
free(tmp); /* free of the node */
|
||||||
|
|
||||||
UNLOCK_RETURN(&q->m, NULL); // end me
|
UNLOCK_RETURN(&q->m, NULL); /* end me */
|
||||||
return data;
|
return data;
|
||||||
|
|
||||||
_end_dequeue:
|
_end_dequeue:
|
||||||
@ -200,7 +199,7 @@ _end_dequeue:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// dequeue until we have s free space and expand the file by s
|
/* dequeue until we have s free space and expand the file by s */
|
||||||
fileT ** dequeueN(queueT *q, char *filepath, size_t s) {
|
fileT ** dequeueN(queueT *q, char *filepath, size_t s) {
|
||||||
if(!q) {
|
if(!q) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
@ -210,11 +209,9 @@ fileT ** dequeueN(queueT *q, char *filepath, size_t s) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCK_RETURN(&q->m, NULL); // begin me
|
LOCK_RETURN(&q->m, NULL); /* begin me */
|
||||||
|
|
||||||
/* TODO: altri oltre a fifo */
|
if (q->head == NULL || q->len == 0) { /* empty queue */
|
||||||
|
|
||||||
if (q->head == NULL || q->len == 0) { // coda vuota
|
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
goto _end_dequeueN;
|
goto _end_dequeueN;
|
||||||
}
|
}
|
||||||
@ -224,21 +221,21 @@ fileT ** dequeueN(queueT *q, char *filepath, size_t s) {
|
|||||||
goto _end_dequeueN;
|
goto _end_dequeueN;
|
||||||
}
|
}
|
||||||
|
|
||||||
// scorro la queue per trovare l'elemento
|
/* try to find the file */
|
||||||
nodeT *tmp = q->head;
|
nodeT *tmp = q->head;
|
||||||
while (tmp) {
|
while (tmp) {
|
||||||
if (strcmp(filepath, (tmp->data)->filepath) == 0) { // trovato
|
if (strcmp(filepath, (tmp->data)->filepath) == 0) { /* found */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!tmp) { // non trovato
|
if(!tmp) { /* not found */
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
goto _end_dequeueN;
|
goto _end_dequeueN;
|
||||||
}
|
}
|
||||||
|
|
||||||
fileT **returnList = NULL; // lista dei file rimossi
|
fileT **returnList = NULL; /* list of removed files */
|
||||||
tmp = NULL;
|
tmp = NULL;
|
||||||
|
|
||||||
returnList = calloc(1, sizeof(fileT*));
|
returnList = calloc(1, sizeof(fileT*));
|
||||||
@ -249,7 +246,7 @@ fileT ** dequeueN(queueT *q, char *filepath, size_t s) {
|
|||||||
purged++;
|
purged++;
|
||||||
returnList = realloc(returnList, purged * sizeof(fileT*));
|
returnList = realloc(returnList, purged * sizeof(fileT*));
|
||||||
if(!returnList) {
|
if(!returnList) {
|
||||||
perror("realloc");
|
perror("dequeueN: realloc");
|
||||||
goto _end_dequeueN;
|
goto _end_dequeueN;
|
||||||
}
|
}
|
||||||
tmp = q->head;
|
tmp = q->head;
|
||||||
@ -259,18 +256,18 @@ fileT ** dequeueN(queueT *q, char *filepath, size_t s) {
|
|||||||
--q->len;
|
--q->len;
|
||||||
q->size -= tmp->data->size;
|
q->size -= tmp->data->size;
|
||||||
|
|
||||||
if (q->head == NULL) { // coda diventa vuota
|
if (q->head == NULL) { /* queue becomes empty */
|
||||||
q->tail = NULL;
|
q->tail = NULL;
|
||||||
break; // we eliminated everything so we must have enought space
|
break; /* we eliminated everything so we must have enought space */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
returnList = realloc(returnList, (purged+1) * sizeof(fileT*));
|
returnList = realloc(returnList, (purged+1) * sizeof(fileT*));
|
||||||
returnList[purged] = NULL; // null terminated
|
returnList[purged] = NULL; /* null terminated */
|
||||||
|
|
||||||
tmp->data->size += s;
|
tmp->data->size += s;
|
||||||
q->size += s;
|
q->size += s;
|
||||||
|
|
||||||
UNLOCK_RETURN(&q->m, NULL); // end me
|
UNLOCK_RETURN(&q->m, NULL); /* end me */
|
||||||
return returnList;
|
return returnList;
|
||||||
|
|
||||||
_end_dequeueN:
|
_end_dequeueN:
|
||||||
@ -284,9 +281,9 @@ void voidDequeue(queueT *q) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCK(&q->m); // begin me
|
LOCK(&q->m); /* begin me */
|
||||||
|
|
||||||
if (q->head == NULL || q->len == 0) { // coda vuota
|
if (q->head == NULL || q->len == 0) { /* empty queue */
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
goto _end_void_dequeue;
|
goto _end_void_dequeue;
|
||||||
}
|
}
|
||||||
@ -296,17 +293,17 @@ void voidDequeue(queueT *q) {
|
|||||||
|
|
||||||
q->head = (q->head)->next;
|
q->head = (q->head)->next;
|
||||||
|
|
||||||
if (q->head == NULL) { // coda diventa vuota
|
if (q->head == NULL) { /* queue becomes empty */
|
||||||
q->tail = NULL;
|
q->tail = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
--q->len;
|
--q->len;
|
||||||
q->size -= (tmp->data)->size;
|
q->size -= (tmp->data)->size;
|
||||||
|
|
||||||
destroyFile(tmp->data); // free fileT
|
destroyFile(tmp->data); /* free fileT */
|
||||||
free(tmp); // free nodo
|
free(tmp); /* free node */
|
||||||
|
|
||||||
UNLOCK(&q->m); // end me
|
UNLOCK(&q->m); /* end me */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_end_void_dequeue:
|
_end_void_dequeue:
|
||||||
@ -314,69 +311,70 @@ _end_void_dequeue:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// print queue
|
/* print queue */
|
||||||
int printQueue(FILE *stream, queueT *q) {
|
int printQueue(FILE *stream, queueT *q) {
|
||||||
if(!q || !stream) {
|
if(!q || !stream) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCK_RETURN(&q->m, -1); // begin me
|
LOCK_RETURN(&q->m, -1); /* begin me */
|
||||||
|
|
||||||
nodeT *tmp = q->head;
|
nodeT *tmp = q->head;
|
||||||
|
|
||||||
fprintf(stream, "Lista file:\n");
|
fprintf(stream, "Lista file:\n");
|
||||||
fprintf(stream, "[Nome File] -> Dimensione in MB\n");
|
fprintf(stream, "[Nome File] -> Dimensione in MB\n");
|
||||||
while (tmp!=NULL) {
|
while (tmp!=NULL) {
|
||||||
float res = ((float)(tmp->data)->size)/1000000; // in MB
|
float res = ((float)(tmp->data)->size)/1000000; /* in MB */
|
||||||
// float res = ((float)(tmp->data)->valid)/1000000; // in MB
|
// float res = ((float)(tmp->data)->valid)/1000000; /* in MB */
|
||||||
fprintf(stream, "[%s] -> %f MB\n", (tmp->data)->filepath, res);
|
fprintf(stream, "[%s] -> %f MB\n", (tmp->data)->filepath, res);
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
UNLOCK_RETURN(&q->m, -1); // end me
|
UNLOCK_RETURN(&q->m, -1); /* end me */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// acquisizione lock
|
/* acquire lock */
|
||||||
int lockFileInQueue(queueT *q, char *filepath, int owner) {
|
int lockFileInQueue(queueT *q, char *filepath, int owner) {
|
||||||
if(!q || !filepath) {
|
if(!q || !filepath) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCK_RETURN(&q->m, -1); // begin me
|
LOCK_RETURN(&q->m, -1); /* begin me */
|
||||||
|
|
||||||
if (q->len == 0) {
|
if (q->len == 0) {
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
goto _end_lock_file_queue;
|
goto _end_lock_file_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// scorro la queue per trovare l'elemento
|
/* find file */
|
||||||
nodeT *tmp = q->head;
|
nodeT *tmp = q->head;
|
||||||
|
|
||||||
while (tmp) {
|
while (tmp) {
|
||||||
if (strcmp(filepath, (tmp->data)->filepath) == 0) { // trovato
|
if (strcmp(filepath, (tmp->data)->filepath) == 0) { /* found */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!tmp) { // non trovato
|
if(!tmp) { /* not found */
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
goto _end_lock_file_queue;
|
goto _end_lock_file_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((tmp->data)->O_LOCK && (tmp->data)->owner != owner) { // lock non del owner
|
/* lock already aquired by another client */
|
||||||
|
if ((tmp->data)->O_LOCK && (tmp->data)->owner != owner) {
|
||||||
errno = EPERM;
|
errno = EPERM;
|
||||||
goto _end_lock_file_queue;
|
goto _end_lock_file_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// acquisisco lock sul file
|
/* aquire lock on the file */
|
||||||
(tmp->data)->O_LOCK = 1;
|
(tmp->data)->O_LOCK = 1;
|
||||||
(tmp->data)->owner = owner;
|
(tmp->data)->owner = owner;
|
||||||
|
|
||||||
UNLOCK_RETURN(&q->m, -1); // end me
|
UNLOCK_RETURN(&q->m, -1); /* end me */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
_end_lock_file_queue:
|
_end_lock_file_queue:
|
||||||
@ -391,41 +389,42 @@ int unlockFileInQueue(queueT *q, char *filepath, int owner) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCK_RETURN(&q->m, -1); // begin me
|
LOCK_RETURN(&q->m, -1); /* begin me */
|
||||||
|
|
||||||
if (q->len == 0) {
|
if (q->len == 0) {
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
goto _end_unlock_file_queue;
|
goto _end_unlock_file_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// scorro la queue per trovare l'elemento
|
/* find the file */
|
||||||
nodeT *tmp = q->head;
|
nodeT *tmp = q->head;
|
||||||
|
|
||||||
while (tmp) {
|
while (tmp) {
|
||||||
if (strcmp(filepath, (tmp->data)->filepath) == 0) { // trovato
|
if (strcmp(filepath, (tmp->data)->filepath) == 0) { /* found */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!tmp) { // non trovato
|
if(!tmp) { /* not found */
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
goto _end_unlock_file_queue;
|
goto _end_unlock_file_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((tmp->data)->O_LOCK == 0) { // nessuno ha il lock
|
if((tmp->data)->O_LOCK == 0) { /* no one has the lock */
|
||||||
UNLOCK_RETURN(&q->m, -1);
|
UNLOCK_RETURN(&q->m, -1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((tmp->data)->O_LOCK == 1 && (tmp->data)->owner != owner) { // lock non del owner
|
/* another client holds the lock */
|
||||||
|
if((tmp->data)->O_LOCK == 1 && (tmp->data)->owner != owner) {
|
||||||
errno = EPERM;
|
errno = EPERM;
|
||||||
goto _end_unlock_file_queue;
|
goto _end_unlock_file_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
(tmp->data)->O_LOCK = 0;
|
(tmp->data)->O_LOCK = 0;
|
||||||
|
|
||||||
UNLOCK_RETURN(&q->m, -1); // end me
|
UNLOCK_RETURN(&q->m, -1); /* end me */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
_end_unlock_file_queue:
|
_end_unlock_file_queue:
|
||||||
@ -434,35 +433,35 @@ _end_unlock_file_queue:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// open file
|
/* open file */
|
||||||
int openFileInQueue(queueT *q, char *filepath, int O_LOCK, int owner) {
|
int openFileInQueue(queueT *q, char *filepath, int O_LOCK, int owner) {
|
||||||
if(!q || !filepath) {
|
if(!q || !filepath) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCK_RETURN(&q->m, -1); // begin me
|
LOCK_RETURN(&q->m, -1); /* begin me */
|
||||||
|
|
||||||
if (q->len == 0) {
|
if (q->len == 0) {
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
goto _end_open_file_queue;
|
goto _end_open_file_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// scorro la queue per trovare l'elemento
|
/* find the file */
|
||||||
nodeT *tmp = q->head;
|
nodeT *tmp = q->head;
|
||||||
while (tmp) {
|
while (tmp) {
|
||||||
if (strcmp(filepath, (tmp->data)->filepath) == 0) { // trovato
|
if (strcmp(filepath, (tmp->data)->filepath) == 0) { /* found */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!tmp) { // non trovato
|
if(!tmp) { /* not found */
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
goto _end_open_file_queue;
|
goto _end_open_file_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// lock non del owner
|
/* lock aquired by another client */
|
||||||
if((tmp->data)->O_LOCK == 1 && (tmp->data)->owner != owner) {
|
if((tmp->data)->O_LOCK == 1 && (tmp->data)->owner != owner) {
|
||||||
errno = EPERM;
|
errno = EPERM;
|
||||||
goto _end_open_file_queue;
|
goto _end_open_file_queue;
|
||||||
@ -475,7 +474,7 @@ int openFileInQueue(queueT *q, char *filepath, int O_LOCK, int owner) {
|
|||||||
(tmp->data)->owner = owner;
|
(tmp->data)->owner = owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
UNLOCK_RETURN(&q->m, -1); // end me
|
UNLOCK_RETURN(&q->m, -1); /* end me */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
_end_open_file_queue:
|
_end_open_file_queue:
|
||||||
@ -483,35 +482,36 @@ _end_open_file_queue:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// close and relese lock
|
/* close and relese lock */
|
||||||
int closeFileInQueue(queueT *q, char *filepath, int owner) {
|
int closeFileInQueue(queueT *q, char *filepath, int owner) {
|
||||||
if(!q || !filepath) {
|
if(!q || !filepath) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCK_RETURN(&q->m, -1); // begin me
|
LOCK_RETURN(&q->m, -1); /* begin me */
|
||||||
|
|
||||||
if (q->len == 0) {
|
if (q->len == 0) {
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
goto _end_close_file_queue;
|
goto _end_close_file_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// scorro la queue per trovare l'elemento
|
/* find file */
|
||||||
nodeT *tmp = q->head;
|
nodeT *tmp = q->head;
|
||||||
while (tmp) {
|
while (tmp) {
|
||||||
if (strcmp(filepath, (tmp->data)->filepath) == 0) { // trovato
|
if (strcmp(filepath, (tmp->data)->filepath) == 0) { /* found */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!tmp) { // non trovato
|
if(!tmp) { /* not found */
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
goto _end_close_file_queue;
|
goto _end_close_file_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((tmp->data)->O_LOCK == 1 && (tmp->data)->owner != owner) { // lock non del owner
|
/* lock aquired by another client */
|
||||||
|
if((tmp->data)->O_LOCK == 1 && (tmp->data)->owner != owner) {
|
||||||
errno = EPERM;
|
errno = EPERM;
|
||||||
goto _end_close_file_queue;
|
goto _end_close_file_queue;
|
||||||
}
|
}
|
||||||
@ -520,7 +520,7 @@ int closeFileInQueue(queueT *q, char *filepath, int owner) {
|
|||||||
(tmp->data)->O_LOCK = 0;
|
(tmp->data)->O_LOCK = 0;
|
||||||
(tmp->data)->owner = owner;
|
(tmp->data)->owner = owner;
|
||||||
|
|
||||||
UNLOCK_RETURN(&q->m, -1); // end me
|
UNLOCK_RETURN(&q->m, -1); /* end me */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
_end_close_file_queue:
|
_end_close_file_queue:
|
||||||
@ -538,41 +538,41 @@ int writeFileInQueue(queueT *q, char *filepath, void *data, size_t size, int own
|
|||||||
if(size == 0)
|
if(size == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
LOCK_RETURN(&q->m, -1); // begin me
|
LOCK_RETURN(&q->m, -1); /* begin me */
|
||||||
|
|
||||||
if (q->len == 0) { // coda vuota
|
if (q->len == 0) { /* empty queue */
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
goto _end_write_file_queue;
|
goto _end_write_file_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (q->size + size > q->maxSize) { // non c'e' abbastanza spazio
|
if (q->size + size > q->maxSize) { /* not enough space */
|
||||||
errno = EFBIG;
|
errno = EFBIG;
|
||||||
goto _end_write_file_queue;
|
goto _end_write_file_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// scorro la queue per trovare l'elemento
|
/* find the file */
|
||||||
nodeT *tmp = q->head;
|
nodeT *tmp = q->head;
|
||||||
while (tmp) {
|
while (tmp) {
|
||||||
if (strcmp(filepath, (tmp->data)->filepath) == 0) { // trovato
|
if (strcmp(filepath, (tmp->data)->filepath) == 0) { /* found */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!tmp) { // non trovato
|
if(!tmp) { /* not found */
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
goto _end_write_file_queue;
|
goto _end_write_file_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((tmp->data)->open == 0 || ((tmp->data)->O_LOCK && (tmp->data)->owner != owner)) {
|
if ((tmp->data)->open == 0 || ((tmp->data)->O_LOCK && (tmp->data)->owner != owner)) {
|
||||||
// if file non è aperto o la lock non è del owner
|
/* file is closed or the client does not hold the lock */
|
||||||
errno = EPERM;
|
errno = EPERM;
|
||||||
goto _end_write_file_queue;
|
goto _end_write_file_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// scrivo
|
/* write */
|
||||||
if (((tmp->data)->data = realloc((tmp->data)->data, size)) == NULL) {
|
if (((tmp->data)->data = realloc((tmp->data)->data, size)) == NULL) {
|
||||||
perror("Realloc content");
|
perror("writeFileInQueue: realloc");
|
||||||
goto _end_write_file_queue;
|
goto _end_write_file_queue;
|
||||||
}
|
}
|
||||||
memcpy((tmp->data)->data, data, size);
|
memcpy((tmp->data)->data, data, size);
|
||||||
@ -581,7 +581,7 @@ int writeFileInQueue(queueT *q, char *filepath, void *data, size_t size, int own
|
|||||||
(tmp->data)->valid = size;
|
(tmp->data)->valid = size;
|
||||||
(tmp->data)->size = size;
|
(tmp->data)->size = size;
|
||||||
|
|
||||||
UNLOCK_RETURN(&q->m, -1); // end me
|
UNLOCK_RETURN(&q->m, -1); /* end me */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
_end_write_file_queue:
|
_end_write_file_queue:
|
||||||
@ -598,52 +598,52 @@ int appendFileInQueue(queueT *q, char *filepath, void *data, size_t size, int ow
|
|||||||
if (size == 0)
|
if (size == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
LOCK_RETURN(&q->m, -1); // begin me
|
LOCK_RETURN(&q->m, -1); /* begin me */
|
||||||
|
|
||||||
if (q->len == 0) { // coda vuota
|
if (q->len == 0) { /* empty queue */
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
goto _end_append_file_queue;
|
goto _end_append_file_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (q->size + size > q->maxSize) { // non c'e' abbastanza spazio
|
if (q->size + size > q->maxSize) { /* not enough space */
|
||||||
errno = EFBIG;
|
errno = EFBIG;
|
||||||
goto _end_append_file_queue;
|
goto _end_append_file_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// scorro la queue per trovare l'elemento
|
/* find the file */
|
||||||
nodeT *tmp = q->head;
|
nodeT *tmp = q->head;
|
||||||
while (tmp) {
|
while (tmp) {
|
||||||
if (strcmp(filepath, (tmp->data)->filepath) == 0) { // trovato
|
if (strcmp(filepath, (tmp->data)->filepath) == 0) { /* found */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!tmp) { // non trovato
|
if(!tmp) { /* not found */
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
goto _end_append_file_queue;
|
goto _end_append_file_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((tmp->data)->open == 0 || ((tmp->data)->O_LOCK && (tmp->data)->owner != owner)) {
|
if ((tmp->data)->open == 0 || ((tmp->data)->O_LOCK && (tmp->data)->owner != owner)) {
|
||||||
// if file non è aperto o la lock non è del owner
|
/* file is closed or the client does not hold the lock */
|
||||||
errno = EPERM;
|
errno = EPERM;
|
||||||
goto _end_append_file_queue;
|
goto _end_append_file_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// scrivo
|
/* write */
|
||||||
if (((tmp->data)->data = realloc((tmp->data)->data, (tmp->data)->valid + size)) == NULL) {
|
if (((tmp->data)->data = realloc((tmp->data)->data, (tmp->data)->valid + size)) == NULL) {
|
||||||
perror("Realloc content");
|
perror("appendFileInQueue: realloc");
|
||||||
goto _end_append_file_queue;
|
goto _end_append_file_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(((char *)(tmp->data)->data) + (tmp->data)->valid, data, size);
|
memcpy(((char *)(tmp->data)->data) + (tmp->data)->valid, data, size);
|
||||||
// memmove sarebbe un'alternativa
|
/* memmove could be an alternative */
|
||||||
(tmp->data)->valid += size;
|
(tmp->data)->valid += size;
|
||||||
q->size -= (tmp->data)->size;
|
q->size -= (tmp->data)->size;
|
||||||
(tmp->data)->size = ((tmp->data)->size > (tmp->data)->valid) ? (tmp->data)->size : (tmp->data)->valid;
|
(tmp->data)->size = ((tmp->data)->size > (tmp->data)->valid) ? (tmp->data)->size : (tmp->data)->valid;
|
||||||
q->size += (tmp->data)->size;
|
q->size += (tmp->data)->size;
|
||||||
|
|
||||||
UNLOCK_RETURN(&q->m, -1); // end me
|
UNLOCK_RETURN(&q->m, -1); /* end me */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
_end_append_file_queue:
|
_end_append_file_queue:
|
||||||
@ -658,18 +658,18 @@ int removeFileFromQueue(queueT *q, char *filepath, int owner) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCK_RETURN(&q->m, -1); // begin me
|
LOCK_RETURN(&q->m, -1); /* begin me */
|
||||||
|
|
||||||
if (q->len == 0) { // coda vuota
|
if (q->len == 0) { /* empty queue */
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
goto _end_remove_file_queue;
|
goto _end_remove_file_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// scorro la queue per trovare l'elemento
|
/* find the file */
|
||||||
nodeT *tmp = q->head;
|
nodeT *tmp = q->head;
|
||||||
nodeT *pre = q->head;
|
nodeT *pre = q->head;
|
||||||
while (tmp) {
|
while (tmp) {
|
||||||
if (strcmp(filepath, (tmp->data)->filepath) == 0) { // trovato
|
if (strcmp(filepath, (tmp->data)->filepath) == 0) { /* found */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(pre!=tmp)
|
if(pre!=tmp)
|
||||||
@ -677,24 +677,24 @@ int removeFileFromQueue(queueT *q, char *filepath, int owner) {
|
|||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tmp) { // non trovato
|
if (!tmp) { /* not found */
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
goto _end_remove_file_queue;
|
goto _end_remove_file_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((tmp->data)->O_LOCK) && ((tmp->data)->owner != owner)) {
|
if (((tmp->data)->O_LOCK) && ((tmp->data)->owner != owner)) {
|
||||||
// if lock non è del owner
|
/* lock not by the client */
|
||||||
errno = EPERM;
|
errno = EPERM;
|
||||||
goto _end_remove_file_queue;
|
goto _end_remove_file_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmp == pre) { // file è il primo
|
if (tmp == pre) { /* file is the first */
|
||||||
q->head = tmp->next;
|
q->head = tmp->next;
|
||||||
|
|
||||||
if (tmp->next == NULL) {
|
if (tmp->next == NULL) {
|
||||||
q->tail = tmp;
|
q->tail = tmp;
|
||||||
}
|
}
|
||||||
} else { // file non è il primo
|
} else {
|
||||||
pre->next = tmp->next;
|
pre->next = tmp->next;
|
||||||
|
|
||||||
if (pre->next == NULL) {
|
if (pre->next == NULL) {
|
||||||
@ -704,10 +704,10 @@ int removeFileFromQueue(queueT *q, char *filepath, int owner) {
|
|||||||
|
|
||||||
--q->len;
|
--q->len;
|
||||||
q->size -= (tmp->data)->size;
|
q->size -= (tmp->data)->size;
|
||||||
destroyFile(tmp->data); // free file
|
destroyFile(tmp->data); /* free file */
|
||||||
free(tmp); // free node
|
free(tmp); /* free node */
|
||||||
|
|
||||||
UNLOCK_RETURN(&q->m, -1); // end me
|
UNLOCK_RETURN(&q->m, -1); /* end me */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
_end_remove_file_queue:
|
_end_remove_file_queue:
|
||||||
@ -716,16 +716,16 @@ _end_remove_file_queue:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ----------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
// cerco e ritorno una copia
|
/* search for file and return a copy */
|
||||||
fileT* find(queueT *q, char *filepath) {
|
fileT* find(queueT *q, char *filepath) {
|
||||||
if(!q || !filepath) {
|
if(!q || !filepath) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCK_RETURN(&q->m, NULL); // begin me
|
LOCK_RETURN(&q->m, NULL); /* begin me */
|
||||||
|
|
||||||
if (q->len == 0)
|
if (q->len == 0)
|
||||||
goto _end_find_in_queue;
|
goto _end_find_in_queue;
|
||||||
@ -734,7 +734,7 @@ fileT* find(queueT *q, char *filepath) {
|
|||||||
nodeT *tmp = q->head;
|
nodeT *tmp = q->head;
|
||||||
|
|
||||||
while (tmp) {
|
while (tmp) {
|
||||||
if (strcmp(filepath, (tmp->data)->filepath) == 0) { // trovato
|
if (strcmp(filepath, (tmp->data)->filepath) == 0) { /* trovato */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
@ -743,23 +743,21 @@ fileT* find(queueT *q, char *filepath) {
|
|||||||
if(!tmp)
|
if(!tmp)
|
||||||
goto _end_find_in_queue;
|
goto _end_find_in_queue;
|
||||||
|
|
||||||
// creo una nuova istanza
|
/* create a new instance */
|
||||||
res = createFileT((tmp->data)->filepath, (tmp->data)->O_LOCK, (tmp->data)->owner, (tmp->data)->open);
|
res = createFileT((tmp->data)->filepath, (tmp->data)->O_LOCK, (tmp->data)->owner, (tmp->data)->open);
|
||||||
|
|
||||||
if (!res) {
|
if (!res) {
|
||||||
perror("createFileT res");
|
perror("find: createFileT");
|
||||||
goto _end_find_in_queue;
|
goto _end_find_in_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (writeFileT(res, (tmp->data)->data, (tmp->data)->size) == -1) {
|
if (writeFileT(res, (tmp->data)->data, (tmp->data)->size) == -1) {
|
||||||
perror("writeFileT res");
|
perror("find: writeFileT");
|
||||||
destroyFile(res);
|
destroyFile(res);
|
||||||
goto _end_find_in_queue;
|
goto _end_find_in_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UNLOCK_RETURN(&q->m, NULL); /* end me */
|
||||||
|
|
||||||
UNLOCK_RETURN(&q->m, NULL); // end me
|
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
_end_find_in_queue:
|
_end_find_in_queue:
|
||||||
@ -767,14 +765,14 @@ _end_find_in_queue:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// cerco
|
/* search for file and return result of search */
|
||||||
int searchFile(queueT *q, char *filepath) {
|
int searchFile(queueT *q, char *filepath) {
|
||||||
if(!q || !filepath) {
|
if(!q || !filepath) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCK_RETURN(&q->m, 0); // begin me
|
LOCK_RETURN(&q->m, 0); /* begin me */
|
||||||
|
|
||||||
if (q->len == 0)
|
if (q->len == 0)
|
||||||
goto _end_search_file_in_queue;
|
goto _end_search_file_in_queue;
|
||||||
@ -782,7 +780,7 @@ int searchFile(queueT *q, char *filepath) {
|
|||||||
nodeT *tmp = q->head;
|
nodeT *tmp = q->head;
|
||||||
|
|
||||||
while (tmp) {
|
while (tmp) {
|
||||||
if (strcmp(filepath, (tmp->data)->filepath) == 0) { // trovato
|
if (strcmp(filepath, (tmp->data)->filepath) == 0) { /* found */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
@ -791,7 +789,7 @@ int searchFile(queueT *q, char *filepath) {
|
|||||||
if(!tmp)
|
if(!tmp)
|
||||||
goto _end_search_file_in_queue;
|
goto _end_search_file_in_queue;
|
||||||
|
|
||||||
UNLOCK_RETURN(&q->m, 0); // end me
|
UNLOCK_RETURN(&q->m, 0); /* end me */
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
_end_search_file_in_queue:
|
_end_search_file_in_queue:
|
||||||
@ -799,7 +797,7 @@ _end_search_file_in_queue:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// numero di elementi della queue
|
/* number of elements in queue */
|
||||||
size_t getLen(queueT *q) {
|
size_t getLen(queueT *q) {
|
||||||
if(!q) {
|
if(!q) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
@ -807,15 +805,15 @@ size_t getLen(queueT *q) {
|
|||||||
}
|
}
|
||||||
size_t len = -1;
|
size_t len = -1;
|
||||||
|
|
||||||
LOCK_RETURN(&q->m, -1); // begin me
|
LOCK_RETURN(&q->m, -1); /* begin me */
|
||||||
|
|
||||||
len = q->len;
|
len = q->len;
|
||||||
|
|
||||||
UNLOCK_RETURN(&q->m, -1); // end me
|
UNLOCK_RETURN(&q->m, -1); /* end me */
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
// dimensione in byte
|
/* size in bytes of queue */
|
||||||
size_t getSize(queueT *q) {
|
size_t getSize(queueT *q) {
|
||||||
if(!q) {
|
if(!q) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
@ -823,11 +821,11 @@ size_t getSize(queueT *q) {
|
|||||||
}
|
}
|
||||||
size_t size = -1;
|
size_t size = -1;
|
||||||
|
|
||||||
LOCK_RETURN(&q->m, -1); // begin me
|
LOCK_RETURN(&q->m, -1); /* begin me */
|
||||||
|
|
||||||
size = q->size;
|
size = q->size;
|
||||||
|
|
||||||
UNLOCK_RETURN(&q->m, -1); // end me
|
UNLOCK_RETURN(&q->m, -1); /* end me */
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -835,12 +833,12 @@ void destroyQueue(queueT *q) {
|
|||||||
if(!q)
|
if(!q)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// no need for lock over queue
|
/* no need for lock over queue */
|
||||||
while (q->len > 0) {
|
while (q->len > 0) {
|
||||||
errno = 0;
|
errno = 0;
|
||||||
voidDequeue(q);
|
voidDequeue(q);
|
||||||
if (errno) {
|
if (errno) {
|
||||||
perror("voiDequeue");
|
perror("destroyQueue: voidDequeue");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,62 +5,62 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
#include <conn.h>
|
#include "conn.h"
|
||||||
|
|
||||||
// struttura dati per gestire i file in memoria principale
|
/* struttura dati per gestire i file in memoria principale */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *filepath; // path assoluto del file
|
char *filepath; /* path assoluto del file */
|
||||||
int O_LOCK; // 1 se il file e' in modalita' locked
|
int O_LOCK; /* 1 se il file e' in modalita' locked */
|
||||||
int owner; // client che possiede la lock sul file
|
int owner; /* client che possiede la lock sul file */
|
||||||
int open; // 1 se il file e' aperto
|
int open; /* 1 se il file e' aperto */
|
||||||
void *data; // contenuto del file
|
void *data; /* contenuto del file */
|
||||||
size_t size; // dimensione del file in bytes
|
size_t size; /* dimensione del file in bytes */
|
||||||
size_t valid; // posizione fino a cui i dati sono validi
|
size_t valid; /* posizione fino a cui i dati sono validi */
|
||||||
} fileT;
|
} fileT;
|
||||||
|
|
||||||
// nodo di una linked list
|
/* nodo di una linked list */
|
||||||
typedef struct node {
|
typedef struct node {
|
||||||
fileT *data;
|
fileT *data;
|
||||||
struct node *next;
|
struct node *next;
|
||||||
} nodeT;
|
} nodeT;
|
||||||
|
|
||||||
// coda FIFO
|
/* coda FIFO */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
nodeT *head; // puntatore al primo elemento
|
nodeT *head; /* puntatore al primo elemento */
|
||||||
nodeT *tail; // puntatore all'ultimo elemento
|
nodeT *tail; /* puntatore all'ultimo elemento */
|
||||||
size_t maxLen; // numero massimo di elementi
|
size_t maxLen; /* numero massimo di elementi */
|
||||||
size_t len; // numero attuale di elementi
|
size_t len; /* numero attuale di elementi */
|
||||||
size_t maxSize; // dimensione massima
|
size_t maxSize; /* dimensione massima */
|
||||||
size_t size; // dimensione attuale
|
size_t size; /* dimensione attuale */
|
||||||
pthread_mutex_t m; // lock sulla coda
|
pthread_mutex_t m; /* lock sulla coda */
|
||||||
} queueT;
|
} queueT;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creazione di un fileT.
|
* Creazione di un fileT.
|
||||||
* \param f: string che identifica il fileT tramite il suo path assoluto
|
* @param f: string che identifica il fileT tramite il suo path assoluto
|
||||||
* \param O_LOCK: 1 locked, 0 unlocked
|
* @param O_LOCK: 1 locked, 0 unlocked
|
||||||
* \param client: client associato
|
* @param client: client associato
|
||||||
* \param open: apertura del file dopo la creazione
|
* @param open: apertura del file dopo la creazione
|
||||||
*
|
*
|
||||||
* \retval puntatore al fileT, NULL se errore (errno)
|
* @return puntatore al fileT, NULL se errore (errno)
|
||||||
*/
|
*/
|
||||||
fileT* createFileT(char *f, int O_LOCK, int client, int open);
|
fileT* createFileT(char *f, int O_LOCK, int client, int open);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Append su un fileT.
|
* Append su un fileT.
|
||||||
* \param f: fileT sul quale scrivere
|
* @param f: fileT sul quale scrivere
|
||||||
* \param data: puntatore al buffer da scrivere
|
* @param data: puntatore al buffer da scrivere
|
||||||
* \param size: dimensione in bytes del buffer
|
* @param size: dimensione in bytes del buffer
|
||||||
*
|
*
|
||||||
* \retval 0 se successo, -1 se errore (errno)
|
* @return 0 se successo, -1 se errore (errno)
|
||||||
*/
|
*/
|
||||||
int writeFileT(fileT *f, void *data, size_t size);
|
int writeFileT(fileT *f, void *data, size_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rimozione di un fileT.
|
* Rimozione di un fileT.
|
||||||
* \param f
|
* @param f
|
||||||
*/
|
*/
|
||||||
void destroyFile(fileT *f);
|
void destroyFile(fileT *f);
|
||||||
|
|
||||||
@ -69,37 +69,37 @@ void destroyFile(fileT *f);
|
|||||||
/**
|
/**
|
||||||
* Alloca ed inizializza una coda di fileT. Deve essere chiamata da un solo
|
* Alloca ed inizializza una coda di fileT. Deve essere chiamata da un solo
|
||||||
* thread.
|
* thread.
|
||||||
* \param maxLen: lunghezza massima della coda
|
* @param maxLen: lunghezza massima della coda
|
||||||
* \param maxSize: dimensione massima della coda in bytes
|
* @param maxSize: dimensione massima della coda in bytes
|
||||||
*
|
*
|
||||||
* \retval puntatore alla coda allocata, NULL se errore
|
* @return puntatore alla coda allocata, NULL se errore
|
||||||
*/
|
*/
|
||||||
queueT* createQueue(size_t maxLen, size_t maxSize);
|
queueT* createQueue(size_t maxLen, size_t maxSize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inserisce un fileT nella coda.
|
* Inserisce un fileT nella coda.
|
||||||
* \param q: puntatore alla coda
|
* @param q: puntatore alla coda
|
||||||
* \param data: puntatore al fileT da inserire
|
* @param data: puntatore al fileT da inserire
|
||||||
*
|
*
|
||||||
* \retval 0 se successo, -1 se errore (errno)
|
* @return 0 se successo, -1 se errore (errno)
|
||||||
*/
|
*/
|
||||||
int enqueue(queueT *q, fileT* data);
|
int enqueue(queueT *q, fileT* data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Estrae un fileT dalla coda.
|
* Estrae un fileT dalla coda.
|
||||||
* \param q: puntatore alla coda
|
* @param q: puntatore alla coda
|
||||||
*
|
*
|
||||||
* \retval puntatore al file estratto, NULL se errore
|
* @return puntatore al file estratto, NULL se errore
|
||||||
*/
|
*/
|
||||||
fileT* dequeue(queueT *q);
|
fileT* dequeue(queueT *q);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Estrae fileT dalla coda fino ad ottenere abbastanza spazio in q.
|
* Estrae fileT dalla coda fino ad ottenere abbastanza spazio in q.
|
||||||
* \param q: puntatore alla coda
|
* @param q: puntatore alla coda
|
||||||
* \param filepath: file a cui bisogna aggiungere s di spazio
|
* @param filepath: file a cui bisogna aggiungere s di spazio
|
||||||
* \param s: dimensione da aggiungere al file
|
* @param s: dimensione da aggiungere al file
|
||||||
*
|
*
|
||||||
* \retval puntatore alla lista di file estratti (NULL terminated), NULL se errore
|
* @return puntatore alla lista di file estratti (NULL terminated), NULL se errore
|
||||||
*/
|
*/
|
||||||
fileT ** dequeueN(queueT *q, char *filepath, size_t s);
|
fileT ** dequeueN(queueT *q, char *filepath, size_t s);
|
||||||
|
|
||||||
@ -107,17 +107,17 @@ fileT ** dequeueN(queueT *q, char *filepath, size_t s);
|
|||||||
* Estrae un fileT dalla coda come la dequeue, ma invece di restituire il
|
* Estrae un fileT dalla coda come la dequeue, ma invece di restituire il
|
||||||
* file estratto lo distrugge immediatamente, liberandone la memoria.
|
* file estratto lo distrugge immediatamente, liberandone la memoria.
|
||||||
*
|
*
|
||||||
* \param q: puntatore alla coda
|
* @param q: puntatore alla coda
|
||||||
*/
|
*/
|
||||||
void voidDequeue(queueT *q);
|
void voidDequeue(queueT *q);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stampa l'intero contenuto della coda.
|
* Stampa l'intero contenuto della coda.
|
||||||
* \param stream: file su cui stampare
|
* @param stream: file su cui stampare
|
||||||
* \param q: puntatore alla coda da stampare
|
* @param q: puntatore alla coda da stampare
|
||||||
*
|
*
|
||||||
* \retval 0 se successo, -1 se errore (errno)
|
* @retval 0 se successo, -1 se errore (errno)
|
||||||
*/
|
*/
|
||||||
int printQueue(FILE *stream, queueT *q);
|
int printQueue(FILE *stream, queueT *q);
|
||||||
|
|
||||||
@ -126,81 +126,81 @@ int printQueue(FILE *stream, queueT *q);
|
|||||||
/**
|
/**
|
||||||
* Cerca di ottenere il lock su un fileT, fallisce se un altro client ha gia'
|
* Cerca di ottenere il lock su un fileT, fallisce se un altro client ha gia'
|
||||||
* richiesto la lock
|
* richiesto la lock
|
||||||
* \param q: puntatore alla coda che contiene il fileT
|
* @param q: puntatore alla coda che contiene il fileT
|
||||||
* \param filepath: path assoluto (identificatore) del fileT
|
* @param filepath: path assoluto (identificatore) del fileT
|
||||||
* \param owner: client che ha richiesto l'operazione
|
* @param owner: client che ha richiesto l'operazione
|
||||||
*
|
*
|
||||||
* \retval 0 se successo, -1 se errore (errno)
|
* @return 0 se successo, -1 se errore (errno)
|
||||||
*/
|
*/
|
||||||
int lockFileInQueue(queueT *q, char *filepath, int owner);
|
int lockFileInQueue(queueT *q, char *filepath, int owner);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rilascia il lock di un file, fallisce se non si e' il possessore del lock
|
* Rilascia il lock di un file, fallisce se non si e' il possessore del lock
|
||||||
* \param q: puntatore alla coda che contiene il fileT
|
* @param q: puntatore alla coda che contiene il fileT
|
||||||
* \param filepath -> path assoluto (identificatore) del fileT
|
* @param filepath -> path assoluto (identificatore) del fileT
|
||||||
* \param owner -> client che ha richiesto l'operazione
|
* @param owner -> client che ha richiesto l'operazione
|
||||||
*
|
*
|
||||||
* \retval 0 se successo, -1 se errore (errno)
|
* @return 0 se successo, -1 se errore (errno)
|
||||||
*/
|
*/
|
||||||
int unlockFileInQueue(queueT *q, char *filepath, int owner);
|
int unlockFileInQueue(queueT *q, char *filepath, int owner);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apre un fileT contenuto nella coda. Fallisce se il lock appartiene a un
|
* Apre un fileT contenuto nella coda. Fallisce se il lock appartiene a un
|
||||||
* client diverso.
|
* client diverso.
|
||||||
* \param q: puntatore alla coda che contiene il fileT da aprire
|
* @param q: puntatore alla coda che contiene il fileT da aprire
|
||||||
* \param filepath: path assoluto (identificatore) del fileT da aprire
|
* @param filepath: path assoluto (identificatore) del fileT da aprire
|
||||||
* \param O_LOCK: 1 locked, 0 unlocked
|
* @param O_LOCK: 1 locked, 0 unlocked
|
||||||
* \param owner: client che ha richiesto l'apertura
|
* @param owner: client che ha richiesto l'apertura
|
||||||
*
|
*
|
||||||
* \retval 0 se successo, -1 se errore (errno)
|
* @return 0 se successo, -1 se errore (errno)
|
||||||
*/
|
*/
|
||||||
int openFileInQueue(queueT *q, char *filepath, int O_LOCK, int owner);
|
int openFileInQueue(queueT *q, char *filepath, int O_LOCK, int owner);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chiude un file contenuto nella coda. Ha successo se fileT non e' stato aperto.
|
* Chiude un file contenuto nella coda. Ha successo se fileT non e' stato aperto.
|
||||||
* Fallisce se il file e' stato messo in modalita' locked da un client diverso.
|
* Fallisce se il file e' stato messo in modalita' locked da un client diverso.
|
||||||
* \param q: puntatore alla coda che contiene il fileT da chiudere
|
* @param q: puntatore alla coda che contiene il fileT da chiudere
|
||||||
* \param filepath: path assoluto (identificatore) del fileT da chiudere
|
* @param filepath: path assoluto (identificatore) del fileT da chiudere
|
||||||
* \param owner: client che ha richiesto la chiusura
|
* @param owner: client che ha richiesto la chiusura
|
||||||
*
|
*
|
||||||
* \retval 0 se successo, -1 se errore (errno)
|
* @return 0 se successo, -1 se errore (errno)
|
||||||
*/
|
*/
|
||||||
int closeFileInQueue(queueT *q, char *filepath, int owner);
|
int closeFileInQueue(queueT *q, char *filepath, int owner);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scrive del contenuto su un fileT all'interno della coda. Fallisce se il file
|
* Scrive del contenuto su un fileT all'interno della coda. Fallisce se il file
|
||||||
* non e' stato aperto o se il lock appartiene a un client diverso.
|
* non e' stato aperto o se il lock appartiene a un client diverso.
|
||||||
* \param q: puntatore alla coda che contiene il fileT su cui scrivere
|
* @param q: puntatore alla coda che contiene il fileT su cui scrivere
|
||||||
* \param filepath: path assoluto (identificatore) del fileT
|
* @param filepath: path assoluto (identificatore) del fileT
|
||||||
* \param data: buffer che contiene i dati
|
* @param data: buffer che contiene i dati
|
||||||
* \param size: dimensione in bytes del buffer
|
* @param size: dimensione in bytes del buffer
|
||||||
* \param owner: client che ha richiesto l'operazione di scrittura
|
* @param owner: client che ha richiesto l'operazione di scrittura
|
||||||
*
|
*
|
||||||
* \retval 0 se successo, -1 se errore (errno)
|
* @return 0 se successo, -1 se errore (errno)
|
||||||
*/
|
*/
|
||||||
int writeFileInQueue(queueT *q, char *filepath, void *data, size_t size, int owner);
|
int writeFileInQueue(queueT *q, char *filepath, void *data, size_t size, int owner);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scrive del contenuto in append su un fileT all'interno della coda. Fallisce
|
* Scrive del contenuto in append su un fileT all'interno della coda. Fallisce
|
||||||
* se il file non e' stato aperto o se il lock appartiene a un client diverso.
|
* se il file non e' stato aperto o se il lock appartiene a un client diverso.
|
||||||
* \param q: puntatore alla coda che contiene il fileT su cui effettuare l'append
|
* @param q: puntatore alla coda che contiene il fileT su cui effettuare l'append
|
||||||
* \param filepath: path assoluto (identificatore) del fileT
|
* @param filepath: path assoluto (identificatore) del fileT
|
||||||
* \param data: buffer che contiene i dati
|
* @param data: buffer che contiene i dati
|
||||||
* \param size: dimensione in bytes del buffer
|
* @param size: dimensione in bytes del buffer
|
||||||
* \param owner: client che ha richiesto l'operazione di append
|
* @param owner: client che ha richiesto l'operazione di append
|
||||||
*
|
*
|
||||||
* \retval 0 se successo, -1 se errore (setta errno)
|
* @return 0 se successo, -1 se errore (setta errno)
|
||||||
*/
|
*/
|
||||||
int appendFileInQueue(queueT *q, char *filepath, void *data, size_t size, int owner);
|
int appendFileInQueue(queueT *q, char *filepath, void *data, size_t size, int owner);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rimuove un fileT dalla coda. Fallisce se non si è in possesso della lock o se
|
* Rimuove un fileT dalla coda. Fallisce se non si è in possesso della lock o se
|
||||||
* la lock e' posseduta da un client diverso.
|
* la lock e' posseduta da un client diverso.
|
||||||
* \param q: puntatore alla coda che contiene il fileT da rimuovere
|
* @param q: puntatore alla coda che contiene il fileT da rimuovere
|
||||||
* \param filepath: path assoluto (identificatore) del fileT da rimuovere
|
* @param filepath: path assoluto (identificatore) del fileT da rimuovere
|
||||||
* \param owner: client che ha richiesto la rimozione
|
* @param owner: client che ha richiesto la rimozione
|
||||||
*
|
*
|
||||||
* \retval 0 se successo, -1 se errore (errno)
|
* @return 0 se successo, -1 se errore (errno)
|
||||||
*/
|
*/
|
||||||
int removeFileFromQueue(queueT *q, char *filepath, int owner);
|
int removeFileFromQueue(queueT *q, char *filepath, int owner);
|
||||||
|
|
||||||
@ -208,42 +208,42 @@ int removeFileFromQueue(queueT *q, char *filepath, int owner);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Cerca un fileT nella coda e ritorna una copia.
|
* Cerca un fileT nella coda e ritorna una copia.
|
||||||
* \param q: puntatore alla coda sulla quale cercare il fileT
|
* @param q: puntatore alla coda sulla quale cercare il fileT
|
||||||
* \param filepath: path assoluto del fileT da cercare
|
* @param filepath: path assoluto del fileT da cercare
|
||||||
*
|
*
|
||||||
* \retval puntatore a una copia del fileT se trovato, NULL se non trovato o errore (errno)
|
* @return puntatore a una copia del fileT se trovato, NULL se non trovato o errore (errno)
|
||||||
*/
|
*/
|
||||||
fileT* find(queueT *q, char *filepath);
|
fileT* find(queueT *q, char *filepath);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cerca il fileT nella coda e ritorna il siultato dell'operazione
|
* Cerca il fileT nella coda e ritorna il siultato dell'operazione
|
||||||
* \param q: puntatore alla coda sulla quale cercare il fileT
|
* @param q: puntatore alla coda sulla quale cercare il fileT
|
||||||
* \param filepath: path assoluto del fileT da cercare
|
* @param filepath: path assoluto del fileT da cercare
|
||||||
*
|
*
|
||||||
* \retval 0 se non trovato, 1 se trovato
|
* @return 0 se non trovato, 1 se trovato
|
||||||
*/
|
*/
|
||||||
int searchFile(queueT *q, char *filepath);
|
int searchFile(queueT *q, char *filepath);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Numero di elementi presenti nella coda.
|
* Numero di elementi presenti nella coda.
|
||||||
* \param q: puntatore alla coda
|
* @param q: puntatore alla coda
|
||||||
*
|
*
|
||||||
* \retval numero di elementi presenti, -1 se errore (errno)
|
* @return numero di elementi presenti, -1 se errore (errno)
|
||||||
*/
|
*/
|
||||||
size_t getLen(queueT *q);
|
size_t getLen(queueT *q);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restituisce la dimensione attuale della coda in bytes.
|
* Restituisce la dimensione attuale della coda in bytes.
|
||||||
* \param q: puntatore alla coda
|
* @param q: puntatore alla coda
|
||||||
*
|
*
|
||||||
* \retval dimensione della coda in bytes, -1 se errore (errno)
|
* @return dimensione della coda in bytes, -1 se errore (errno)
|
||||||
*/
|
*/
|
||||||
size_t getSize(queueT *q);
|
size_t getSize(queueT *q);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancella una coda allocata con createQueue e ne libera la memoria.
|
* Cancella una coda allocata con createQueue e ne libera la memoria.
|
||||||
* \param q: puntatore alla coda da distruggere
|
* @param q: puntatore alla coda da distruggere
|
||||||
*/
|
*/
|
||||||
void destroyQueue(queueT *q);
|
void destroyQueue(queueT *q);
|
||||||
|
|
||||||
#endif // _FILE_QUEUE
|
#endif /* _FILE_QUEUE */
|
||||||
|
|||||||
Reference in New Issue
Block a user