diff --git a/Project/Client/client b/Project/Client/client old mode 100644 new mode 100755 diff --git a/Project/Server/Makefile b/Project/Server/Makefile index ed924c7..d882d97 100644 --- a/Project/Server/Makefile +++ b/Project/Server/Makefile @@ -1,7 +1,7 @@ CC=cc FLAGS=-c -Wall LIBS=-lm -lpthread -OBS=source_server.o msg.o fila.o server.o connection.o ftp.o send_struct.o +OBS=source_server.o msg.o fila.o server.o connection.o ftp.o send_struct.o lock.o all : source_server @@ -15,7 +15,10 @@ fila.o : fila.h fila.c ftp.o : ftp.h fifo.h ftp.c $(CC) $(FLAGS) ftp.c -send_struct.o : send_struct.h send_struct.c +lock.o : lock.h lock.c + $(CC) $(FLAGS) lock.c + +send_struct.o : send_struct.h lock.h send_struct.c $(CC) $(FLAGS) send_struct.c connection.o : fifo.h connection.h connection.c @@ -24,7 +27,7 @@ connection.o : fifo.h connection.h connection.c source_server.o : server.h fifo.h source_server.c $(CC) $(FLAGS) source_server.c -server.o : send_struct.h server.h ftp.h connection.h fila.h fifo.h server.c +server.o : send_struct.h server.h ftp.h connection.h lock.h fila.h fifo.h server.c $(CC) $(FLAGS) server.c diff --git a/Project/Server/lock.c b/Project/Server/lock.c new file mode 100644 index 0000000..4411e42 --- /dev/null +++ b/Project/Server/lock.c @@ -0,0 +1,63 @@ +#include +#include +#include "lock.h" + +sem_t sem_lock; +sem_t sem_unlock; + +void lock_sem_init(void) +{ + sem_init(&sem_lock, 0, 1); + sem_init(&sem_unlock, 0, 1); +} + +int lock(int *L, int size, int index) +{ + if (index <= -1 || index >= size) + return 0; + + sem_wait(&sem_lock); + if (L[index] == 0) + L[index] = 1; + else + { + sem_post(&sem_lock); + return 0; + } + + sem_post(&sem_lock); + return 1; +} + +int unlock(int *L, int size, int index) +{ + if (index <= -1 || index >= size) + return 0; + + sem_wait(&sem_unlock); + + if (L[index] == 1) + L[index] = 0; + else + { + sem_post(&sem_unlock); + return 0; + } + + sem_post(&sem_unlock); + return 1; +} + +int *locks_insert_node(int *L, int *size) +{ + (*size)++; + + if (*size == 1) + L = (int *)malloc(sizeof(int)); + else + L = (int *)realloc(L, (*size) * sizeof(int)); + + L[*size - 1] = 0; + + return L; +} diff --git a/Project/Server/lock.h b/Project/Server/lock.h new file mode 100644 index 0000000..644b029 --- /dev/null +++ b/Project/Server/lock.h @@ -0,0 +1,12 @@ +#ifndef LOCK_H +#define LOCK_H + +void lock_sem_init(void); + +int lock(int *L, int size, int index); + +int unlock(int *L, int size, int index); + +int* locks_insert_node(int *L, int *size); + +#endif // LOCK_H \ No newline at end of file diff --git a/Project/Server/send_struct.c b/Project/Server/send_struct.c index 63abf0c..69880c9 100644 --- a/Project/Server/send_struct.c +++ b/Project/Server/send_struct.c @@ -1,6 +1,10 @@ -#include "send_struct.h" #include #include +#include "send_struct.h" +#include "lock.h" + +int *locks = NULL; +int size = 0; void send_handle(Connection *connection, Fila **filas) { @@ -42,51 +46,117 @@ int send_fila(Connection connection, Fila *L) { Fila *aux = L; int resposta = -1; + int lock_error = 0; + int lock_index_error = 0; + int i = 0; + + for (i = 0; i < size; i++) + if (!lock(locks, size, i)) + { + lock_error = -1; + lock_index_error = i; + break; + } + + if (lock_error == -1) + { + for (i = 0; i < lock_index_error; i++) + unlock(locks, size, i); + + write(connection.fifosfd, &resposta, sizeof(resposta)); + return -1; + } // Enviar os ids while (aux != NULL) { if (write(connection.fifosfd, &aux->id, sizeof(aux->id)) == -1) + { + for (i = 0; i < lock_index_error; i++) + unlock(locks, size, i); + + write(connection.fifosfd, &resposta, sizeof(resposta)); return -1; + } + aux = aux->p_seg; } // Informar que terminou if (write(connection.fifosfd, &resposta, sizeof(resposta)) == -1) + { + for (i = 0; i < lock_index_error; i++) + unlock(locks, size, i); + + write(connection.fifosfd, &resposta, sizeof(resposta)); return -1; + } + + for (i = 0; i < lock_index_error; i++) + unlock(locks, size, i); + return 0; } int send_fila_add(Connection connection, Fila **L) { int id = fila_max_id(*L) + 1; + int error = -1; + + if (size > 0) + if (lock(locks, size, id - 2) == 0) + { + write(connection.fifosfd, &error, sizeof(int)); + return error; + } + *L = fila_insert_node(*L, fila_make_node(id, NULL)); + locks = locks_insert_node(locks, &size); - if (write(connection.fifosfd, &id, sizeof(int)) == -1) - return -1; + if (write(connection.fifosfd, &id, sizeof(int)) == error) + { + unlock(locks, size, id - 2); + return error; + } + unlock(locks, size, id - 2); return 0; } int send_fila_msg(Connection connection, Fila *L) { - int id; - int erro = -1; Fila *fila = NULL; Msg *aux = NULL; int resposta = -1; // -1 -> fim da fila + int erro = -1; + int id = 0; // Receber id da Fila if (read(connection.fifocfd, &id, sizeof(int)) == -1) return -1; + if (!lock(locks, size, id - 1)) + { + if (write(connection.fifosfd, &erro, sizeof(int)) == -1) + return -1; + if (erro == -1) + return -1; + } + fila = fila_find_node(L, id); erro = fila == NULL ? -1 : 1; if (write(connection.fifosfd, &erro, sizeof(int)) == -1) + { + unlock(locks, size, id - 1); return -1; + } + if (erro == -1) + { + unlock(locks, size, id - 1); return -1; + } aux = fila->mensagens; @@ -94,122 +164,202 @@ int send_fila_msg(Connection connection, Fila *L) while (aux != NULL) { if (write(connection.fifosfd, &aux->id, sizeof(int)) == -1) + { + unlock(locks, size, id - 1); return -1; + } + aux = aux->p_seg; } // Informar que terminou if (write(connection.fifosfd, &resposta, sizeof(int)) == -1) + { + unlock(locks, size, id - 1); return -1; + } + unlock(locks, size, id - 1); return 1; } int send_msg_content(Connection connection, Fila *L) { - int id = 0; + int filaId = 0; + int msgId = 0; int erro = -1; Fila *fila = NULL; Msg *msg = NULL; // Receber id da Fila - if (read(connection.fifocfd, &id, sizeof(int)) == -1) + if (read(connection.fifocfd, &filaId, sizeof(int)) == -1) return -1; - fila = fila_find_node(L, id); + if (!lock(locks, size, filaId - 1)) + { + if (write(connection.fifosfd, &erro, sizeof(int)) == -1) + return -1; + if (erro == -1) + return -1; + } + + fila = fila_find_node(L, filaId); erro = fila == NULL ? -1 : 1; // Fila não existe if (write(connection.fifosfd, &erro, sizeof(int)) == -1) + { + unlock(locks, size, filaId - 1); return -1; + } if (erro == -1) + { + unlock(locks, size, filaId - 1); return -1; + } // Receber id da Mensagem - if (read(connection.fifocfd, &id, sizeof(int)) == -1) + if (read(connection.fifocfd, &msgId, sizeof(int)) == -1) + { + unlock(locks, size, filaId - 1); return -1; + } - msg = msg_find_node(fila->mensagens, id); + msg = msg_find_node(fila->mensagens, msgId); erro = msg == NULL ? -1 : 1; // Msg não existe if (write(connection.fifosfd, &erro, sizeof(int)) == -1) + { + unlock(locks, size, filaId - 1); return -1; + } + if (erro == -1) + { + unlock(locks, size, filaId - 1); return -1; + } // Envia o conteudo if (write(connection.fifosfd, msg->content, strlen(msg->content)) == -1) + { + unlock(locks, size, filaId - 1); return -1; + } + unlock(locks, size, filaId - 1); return 1; } int send_msg_add(Connection connection, Fila **L) { - int id = 0; - int msg_id = 0; - int n; - int erro = -1; - char content[CONTENT_SIZE]; Fila *fila = NULL; + char content[CONTENT_SIZE]; + int filaId = 0; + int msgId = 0; + int erro = -1; + int n = 0; // Receber id da Fila a inserir - if (read(connection.fifocfd, &id, sizeof(int)) == -1) + if (read(connection.fifocfd, &filaId, sizeof(int)) == -1) return -1; - fila = fila_find_node(*L, id); + if (!lock(locks, size, filaId - 1)) + { + if (write(connection.fifosfd, &erro, sizeof(int)) == -1) + return -1; + if (erro == -1) + return -1; + } + + fila = fila_find_node(*L, filaId); erro = fila == NULL ? -1 : 1; // Fila não existe if (write(connection.fifosfd, &erro, sizeof(int)) == -1) + { + unlock(locks, size, filaId - 1); return -1; + } if (erro == -1) + { + unlock(locks, size, filaId - 1); return -1; + } // Receber conteudo da Mensagem a inserir if ((n = read(connection.fifocfd, content, CONTENT_SIZE - 1)) == -1) + { + unlock(locks, size, filaId - 1); return -1; + } content[n] = '\0'; - msg_id = msg_max_id(fila->mensagens) + 1; - fila->mensagens = msg_insert_node(fila->mensagens, msg_make_node(msg_id, content)); + msgId = msg_max_id(fila->mensagens) + 1; + fila->mensagens = msg_insert_node(fila->mensagens, msg_make_node(msgId, content)); - return 0; + unlock(locks, size, filaId - 1); + return 1; } int send_msg_remove(Connection connection, Fila **L) { - int id; + int filaId = -1; + int msgId = -1; int erro = -1; Fila *fila = *L; // Receber id da Fila - if (read(connection.fifocfd, &id, sizeof(int)) == -1) + if (read(connection.fifocfd, &filaId, sizeof(int)) == -1) return -1; - fila = fila_find_node(*L, id); + if (!lock(locks, size, filaId - 1)) + { + if (write(connection.fifosfd, &erro, sizeof(int)) == -1) + return -1; + if (erro == -1) + return -1; + } + + fila = fila_find_node(*L, filaId); erro = fila == NULL ? -1 : 1; if (write(connection.fifosfd, &erro, sizeof(erro)) == -1) + { + unlock(locks, size, filaId - 1); return -1; + } if (erro == -1) + { + unlock(locks, size, filaId - 1); return -1; + } // Receber id da Mensagem - if (read(connection.fifocfd, &id, sizeof(int)) == -1) + if (read(connection.fifocfd, &msgId, sizeof(int)) == -1) + { + unlock(locks, size, filaId - 1); return -1; + } - Msg *msg = msg_find_node(fila->mensagens, id); + Msg *msg = msg_find_node(fila->mensagens, msgId); fila->mensagens = msg_remove_node(fila->mensagens, msg); erro = msg == NULL ? -1 : 1; // Msg não existe if (write(connection.fifosfd, &erro, sizeof(int)) == -1) + { + unlock(locks, size, filaId - 1); return -1; + } if (erro == -1) + { + unlock(locks, size, filaId - 1); return -1; + } + unlock(locks, size, filaId - 1); return 1; } diff --git a/Project/Server/server.c b/Project/Server/server.c index b31cc55..044c6bc 100644 --- a/Project/Server/server.c +++ b/Project/Server/server.c @@ -7,15 +7,15 @@ #include "send_struct.h" #include "connection.h" #include "server.h" -#include "ftp.h" #include "fila.h" #include "fifo.h" +#include "lock.h" +#include "ftp.h" MainConnection *mainConnection; Connection *connections; Fila *filas = NULL; int *available_connections; -sem_t sem_msg; void do_nothing(int signum) { @@ -65,10 +65,8 @@ void *operation(void *args) connection_close(connection, available_connections); break; case 2: - sem_wait(&sem_msg); send_handle(connection, &filas); connection_close(connection, available_connections); - sem_post(&sem_msg); break; } @@ -77,17 +75,18 @@ void *operation(void *args) void *server(void *args) { - printf("Server On.\n"); - signal(SIGPIPE, do_nothing); - - int resposta = -1; - int pedido = 0; - int index; available_connections = (int *)calloc(MAX_CONNECTIONS, sizeof(int)); mainConnection = (MainConnection *)args; connections = (Connection *)malloc(MAX_CONNECTIONS * sizeof(Connection)); - sem_init(&sem_msg, 0, 1); + int resposta = -1; + int pedido = 0; + int index = 0; + + signal(SIGPIPE, do_nothing); + lock_sem_init(); + + printf("Server On.\n"); while (true) { diff --git a/Project/Server/source_server b/Project/Server/source_server old mode 100644 new mode 100755 index 065f291..b61972e Binary files a/Project/Server/source_server and b/Project/Server/source_server differ diff --git a/Tests/Fila/fila.h b/Tests/Fila/fila.h index 8c109cd..2cc2047 100644 --- a/Tests/Fila/fila.h +++ b/Tests/Fila/fila.h @@ -3,14 +3,6 @@ #include "msg.h" -/* msg_make_node: Makes a Msg node -* -* args: -* id: Msg id -* content: Msg content -* -* return: Node with the given information -*/ typedef struct FILA { int id; diff --git a/Tests/Lock/Makefile b/Tests/Lock/Makefile new file mode 100644 index 0000000..5169b6f --- /dev/null +++ b/Tests/Lock/Makefile @@ -0,0 +1,23 @@ +CC=cc +FLAGS=-c -Wall +LIBS=-lm -lpthread +OBS=lock_teste.o lock.o + +all : lock_teste + + +lock.o : lock.h lock.c + $(CC) $(FLAGS) lock.c + +lock_teste.o : lock.h lock_teste.c + $(CC) $(FLAGS) lock_teste.c + + +lock_teste : $(OBS) + $(CC) -o lock_teste $(OBS) $(LIBS) + + +clean limpar: + rm -f *.o + echo "Limpeza dos ficheiros exectuaveis, objectos e gedit tralha" + \ No newline at end of file diff --git a/Tests/Lock/lock.c b/Tests/Lock/lock.c new file mode 100644 index 0000000..99891f1 --- /dev/null +++ b/Tests/Lock/lock.c @@ -0,0 +1,58 @@ +#include +#include +#include "lock.h" + +sem_t sem_lock; +sem_t sem_unlock; + +void lock_sem_init(void) +{ + sem_init(&sem_lock, 0, 1); + sem_init(&sem_unlock, 0, 1); +} + +int lock(int *L, int size, int index) +{ + if (index >= size || index < 0) + return 0; + + //sem_wait(&sem_lock); + + if (L[index] == 0) + L[index] = 1; + else + return 0; + + //sem_post(&sem_unlock); + return 1; +} + +int unlock(int *L, int size, int index) +{ + if (index >= size || index < 0) + return 0; + + //sem_wait(&sem_lock); + + if (L[index] == 1) + L[index] = 0; + else + return 0; + + //sem_post(&sem_unlock); + return 1; +} + +int *locks_insert_node(int *L, int *size) +{ + (*size)++; + + if (*size == 1) + L = (int *)malloc(sizeof(int)); + else + L = (int *)realloc(L, (*size) * sizeof(int)); + + L[*size - 1] = 0; + + return L; +} diff --git a/Tests/Lock/lock.h b/Tests/Lock/lock.h new file mode 100644 index 0000000..644b029 --- /dev/null +++ b/Tests/Lock/lock.h @@ -0,0 +1,12 @@ +#ifndef LOCK_H +#define LOCK_H + +void lock_sem_init(void); + +int lock(int *L, int size, int index); + +int unlock(int *L, int size, int index); + +int* locks_insert_node(int *L, int *size); + +#endif // LOCK_H \ No newline at end of file diff --git a/Tests/Lock/lock_teste b/Tests/Lock/lock_teste new file mode 100755 index 0000000..7bd7d30 Binary files /dev/null and b/Tests/Lock/lock_teste differ diff --git a/Tests/Lock/lock_teste.c b/Tests/Lock/lock_teste.c new file mode 100644 index 0000000..c76c575 --- /dev/null +++ b/Tests/Lock/lock_teste.c @@ -0,0 +1,48 @@ +#include +#include "lock.h" + +int teste_locks_insert_node(void); +int teste_lock(void); + +int main(void) +{ + printf("teste_locks_insert_node : %d\n", teste_locks_insert_node()); + + printf("teste_lock : %d\n", teste_lock()); + + return 0; +} + +int teste_locks_insert_node(void) +{ + int size = 0; + int *locks = locks_insert_node(NULL, &size); + + //printf("locks[0] = %d\n", locks[0]); + + locks = locks_insert_node(locks, &size); + + locks[size - 1] = 1; + + //printf("locks[size - 1] = %d\n", locks[size - 1]); + + return 1; +} + +int teste_lock(void) +{ + int size = 0; + int *locks = locks_insert_node(NULL, &size); + locks_insert_node(NULL, &size); + locks_insert_node(NULL, &size); + locks_insert_node(NULL, &size); + + lock(locks, size, 0); + printf("locks[0] = %d\n", locks[0]); + + unlock(locks, size, 0); + + printf("locks[0] = %d\n", locks[0]); + + return 1; +} \ No newline at end of file