diff --git a/Building/Building.c b/Building/Building.c index c62e3c0..2b2c7b3 100644 --- a/Building/Building.c +++ b/Building/Building.c @@ -8,8 +8,6 @@ #define LINE_BUFFER 256 -GETTER(Building, Elevator **, elevators) - void remove_end_char(char * string, char character){ size_t string_size = strlen(string); if (string[string_size - 1] == character) @@ -110,6 +108,7 @@ void _free__Building(THIS(Building)){ Building *_init_Building(char * residents_file, char * visitors_file){ Building * new_building = malloc_or_die(sizeof(Building)); + char elevator_name[] = "@"; int i; new_building->floors = FLOORS; @@ -117,13 +116,14 @@ Building *_init_Building(char * residents_file, char * visitors_file){ new_building->residents = NEW(List); new_building->visitors = NEW(List); new_building->box = NEW(CommunicationBox); - for (i=0; ielevators[i] = NEW(Elevator); + for (i=0; ielevators[i] = NEW(Elevator, elevator_name); + } LINK_ALL(Building, new_building, - get_elevators, parse_residents, parse_visitors ) diff --git a/Building/Building.h b/Building/Building.h index b300452..041500e 100644 --- a/Building/Building.h +++ b/Building/Building.h @@ -20,7 +20,6 @@ typedef struct o_Building { CommunicationBox * box; Elevator ** elevators; - SYNCHRONIZE Elevator ** (*get_elevators)(_THIS(Building)); PRIVATE void (*parse_residents)(_THIS(Building), char * file); PRIVATE void (*parse_visitors)(_THIS(Building), char * file); diff --git a/Elevator/Elevator.c b/Elevator/Elevator.c index 50ab7d5..e2ace65 100644 --- a/Elevator/Elevator.c +++ b/Elevator/Elevator.c @@ -2,16 +2,41 @@ // Created by Antoine Bartuccio on 05/06/2018. // +#include #include "Elevator.h" void _free__Elevator(THIS(Elevator)){ + DELETE(this->passenger_ids); + if (this->name != NULL) + free(this->name); + pthread_mutex_unlock(&this->passenger_mutex); + pthread_mutex_destroy(&this->passenger_mutex); free(this); } -Elevator *_init_Elevator(){ - Elevator * new_elevator = malloc_or_die(sizeof(Elevator)); +int get_number_of_passengers_Elevator(THIS(Elevator)){ + int num; + pthread_mutex_lock(&this->passenger_mutex); + num = this->passenger_ids->get_size(this->passenger_ids); + pthread_mutex_lock(&this->passenger_mutex); + return num; +} - LINK(Elevator, new_elevator, _free_); +int can_get_more_passengers_Elevator(_THIS(Elevator)){ + return (this->get_number_of_passengers(this) < MAX_ELEVATOR_CAPACITY); +} + +Elevator *_init_Elevator(char * name){ + Elevator * new_elevator = malloc_or_die(sizeof(Elevator)); + new_elevator->state = waiting; + new_elevator->name = strdup(name); + new_elevator->passenger_ids = NEW(List); + pthread_mutex_init(&new_elevator->passenger_mutex, NULL); + + LINK_ALL(Elevator, new_elevator, + get_number_of_passengers, + can_get_more_passengers + ); return new_elevator; } \ No newline at end of file diff --git a/Elevator/Elevator.h b/Elevator/Elevator.h index c7b51f8..8ee26de 100644 --- a/Elevator/Elevator.h +++ b/Elevator/Elevator.h @@ -5,13 +5,27 @@ #ifndef LO41_ELEVATOR_H #define LO41_ELEVATOR_H +#include #include "../Objects.h" +#include "../List/List.h" + +#define MAX_ELEVATOR_CAPACITY 10 + +typedef enum {running, waiting, sleeping} ELEVATOR_STATE; typedef struct o_Elevator { + PRIVATE ELEVATOR_STATE state; + PRIVATE List * passenger_ids; + PRIVATE char * name; + PRIVATE pthread_mutex_t passenger_mutex; + SYNCHRONIZE PUBLIC int (*get_number_of_passengers)(_THIS(Elevator)); + SYNCHRONIZE PUBLIC int (*can_get_more_passengers(_THIS(Elevator))); DESTRUCTOR(Elevator); } Elevator; -Elevator *_init_Elevator(); +FRIENDLY(state, Building) + +Elevator *_init_Elevator(char* name); #endif //LO41_ELEVATOR_H diff --git a/SharedData/SharedData.c b/SharedData/SharedData.c index 83bd97d..9ce9d95 100644 --- a/SharedData/SharedData.c +++ b/SharedData/SharedData.c @@ -4,7 +4,36 @@ #include "SharedData.h" +SETTER(SharedData, Building *, main_building) + +void wait_threads_SharedData(THIS(SharedData)){ + int i; + for (i=0; ithreads_nb; i++) + pthread_join(this->threads[i], NULL); +} + +int call_elevator_SharedData(THIS(SharedData), int starting_floor, int destination_floor){ + /* Make the thread wait for an elevator available and return the id of the elevator available */ + if (this->main_building == NULL) + CRASH("No building attached to shared data, you cannot call an elevator\n"); + if (starting_floor < 0) + CRASH("You cannot start from a floor lower than 0\n"); + if (destination_floor > FLOORS) + CRASH("You are trying to reach a floor higher than the highest floor\n"); + + return 0; +} + void _free__SharedData(THIS(SharedData)){ + int i; + if (this->threads != NULL){ + for (i=0; ithreads_nb; i++) + pthread_cancel(this->threads[i]); + free(this->threads); + } + if (this->main_building != NULL) + DELETE(this->main_building); + free(this); } @@ -12,7 +41,16 @@ SharedData *_get_instance_SharedData(){ static SharedData * new_shared_data = NULL; if (new_shared_data == NULL){ new_shared_data = malloc_or_die(sizeof(SharedData)); - LINK(SharedData, new_shared_data, _free_); + + new_shared_data->threads = NULL; + new_shared_data->main_building = NULL; /* Should be set to NULL if freed */ + new_shared_data->threads_nb = 0; + + LINK_ALL(SharedData, new_shared_data, + wait_threads, + set_main_building, + call_elevator + ); } return new_shared_data; } diff --git a/SharedData/SharedData.h b/SharedData/SharedData.h index b987897..1f2d6bf 100644 --- a/SharedData/SharedData.h +++ b/SharedData/SharedData.h @@ -5,9 +5,23 @@ #ifndef LO41_SHAREDDATA_H #define LO41_SHAREDDATA_H +#include #include "../Objects.h" +#include "../Building/Building.h" + +#define MUTEX_NB 3 + +enum {mutex_1, mutex_2, mutex_3}; typedef struct o_SharedData { + PRIVATE int threads_nb; + PRIVATE pthread_t *threads; + PRIVATE pthread_mutex_t mutex_array[MUTEX_NB]; + PRIVATE Building * main_building; + + PUBLIC void (*set_main_building)(_THIS(SharedData), Building * building); + PUBLIC void (*wait_threads)(_THIS(SharedData)); + PUBLIC int (*call_elevator)(_THIS(SharedData), int starting_floor, int destination_floor); DESTRUCTOR(SharedData); } SharedData; diff --git a/main.c b/main.c index 6cc2162..b7c9aaf 100644 --- a/main.c +++ b/main.c @@ -1,4 +1,6 @@ #include +#include + #include "Objects.h" #include "List/List.h" #include "Building/Building.h" @@ -6,6 +8,11 @@ #include "Visitor/Visitor.h" #include "Resident/Resident.h" +void clean_exit(int error_code){ + DELETE(GET_INSTANCE(SharedData)); + exit(0); +} + int main() { List *l = NEW(List); Visitor * roger = NEW(Visitor, 8, "Roger"); @@ -14,6 +21,7 @@ int main() { char text2[30] = "Patator"; GET_INSTANCE(SharedData); + signal(SIGINT, clean_exit); printf("La taille est de %d\n", l->get_size(l)); l->insert_tail(l, text1, sizeof(char) * 30); @@ -35,11 +43,15 @@ int main() { printf("Il y a %d étages dans l'immeuble\n", main_building->floors); printf("%s est le second visiteur\n", ((Visitor *) main_building->visitors->get_element_data(main_building->visitors, 1))->name); printf("%s est le second resident\n", ((Resident *) main_building->residents->get_element_data(main_building->residents, 1))->name); + for (int i=0; i < ELEVATOR_NB; i++) + printf("Ascenseur %s\n", main_building->elevators[i]->name); + GET_INSTANCE(SharedData)->main_building = main_building; DELETE(main_building); printf("Hello, World!\n"); printf("%s veut rentrer\n", roger->get_name(roger)); printf("%s habite dans l'appartement %d\n", sli->get_name(sli), sli->get_apartment_floor(sli)); + DELETE(GET_INSTANCE(SharedData)); DELETE(roger); DELETE(sli);