diff --git a/include/hashmap.h b/include/hashmap.h index fc9ae03..4a90775 100644 --- a/include/hashmap.h +++ b/include/hashmap.h @@ -14,19 +14,46 @@ struct hashmap { struct hashmap *next; }; -/* Calculate the hash code of a file descriptor */ +/** + * @brief Calculates the hash code of a given file descriptor + * + * @param sockfd[in] The file descriptor + * @return int Returns the hash code + */ int hash(int sockfd); -/* Initialize the hash map */ +/** + * @brief Initializes the hash map + * + * @param map[out] The hash map uninitialized + */ void hm_init(struct hashmap *map); -/* Insert a new key in the hash map */ -void hm_insert(struct hashmap *map, int sockfd, struct sockaddr_storage *sas); +/** + * @brief Inserts a key in the hash map + * + * @param map[out] The hash map + * @param sockfd[in] The file descriptor (value) + * @param sas[in] The sockaddr (value) + */ +void hm_push(struct hashmap *map, int sockfd, struct sockaddr_storage *sas); -/* Search for a key in the hash map */ +/** + * @brief Searches for a key in the hash map + * + * @param map[in] The hash map + * @param sockfd[in] The file descriptor (key) + * @return struct hashmap* Returns NULL or the key pointer + */ struct hashmap *hm_lookup(struct hashmap *map, int sockfd); -/* Clean up the hash map */ +/** + * @brief Cleans the hash map + * + * @param map[out] The hash map + */ void hm_free(struct hashmap *map); +void hm_insert(struct hashmap *map, int sockfd, struct sockaddr_storage *sas); + #endif \ No newline at end of file diff --git a/src/hashmap.c b/src/hashmap.c index f0e2284..f7b85a6 100644 --- a/src/hashmap.c +++ b/src/hashmap.c @@ -3,6 +3,7 @@ int hash(int sockfd) { return sockfd % HASHMAP_MAX_CLIENTS; } void hm_init(struct hashmap *map) { + /* Initialize everything to 0 for the struct, then -1 for fd and next to NULL */ memset(map, 0, sizeof(struct hashmap) * HASHMAP_MAX_CLIENTS); for (size_t i = 0; i < HASHMAP_MAX_CLIENTS; ++i) { @@ -11,21 +12,23 @@ void hm_init(struct hashmap *map) { } } +/* This function will add a key even if it exists (use hm_push() instead) */ void hm_insert(struct hashmap *map, int sockfd, struct sockaddr_storage *sas) { int index = hash(sockfd); if (map[index].sockfd == -1) { + /* Current slot is empty */ map[index].sockfd = sockfd; map[index].sas = *sas; + map[index].next = NULL; } else { - /* Go through the linked list and append the new item */ - struct hashmap *p; - for (p = &map[index]; p->next != NULL; p = p->next); + /* Append the new key to the head (not the first element because it belongs to the array) of the linked + * list */ + struct hashmap *p = &map[index]; struct hashmap *new = malloc(sizeof(struct hashmap)); new->sockfd = sockfd; new->sas = *sas; - new->next = NULL; - + new->next = p->next; p->next = new; } } @@ -35,7 +38,7 @@ struct hashmap *hm_lookup(struct hashmap *map, int sockfd) { if (map[index].sockfd != sockfd) { struct hashmap *p; - for (p = map[index].next; p->sockfd != sockfd; p = p->next); + for (p = map[index].next; p != NULL && p->sockfd != sockfd; p = p->next); return p; } else { return &map[index]; @@ -44,4 +47,25 @@ struct hashmap *hm_lookup(struct hashmap *map, int sockfd) { return NULL; } -void hm_free(struct hashmap *map) {} +void hm_push(struct hashmap *map, int sockfd, struct sockaddr_storage *sas) { + if (hm_lookup(map, sockfd) == NULL) { + hm_insert(map, sockfd, sas); + } +} + +void hm_free(struct hashmap *map) { + struct hashmap *p, *next; + + for (size_t i = 0; i < HASHMAP_MAX_CLIENTS; ++i) { + if (map[i].next != NULL) { + /* Free the malloc */ + p = map[i].next; + next = p->next; + do { + free(p); + p = next; + next = p != NULL ? p->next : NULL; + } while (p != NULL); + } + } +} diff --git a/src/server.c b/src/server.c index 04b083a..c64df49 100644 --- a/src/server.c +++ b/src/server.c @@ -78,7 +78,7 @@ void handle_clients(int sockfd) { setnonblocking(client_fd); epoll_ctl_add(epfd, client_fd, EPOLLIN); - hm_insert(clients, client_fd, &their_sa); + hm_push(clients, client_fd, &their_sa); int bytes_sent = send(client_fd, msg, msg_len, 0); fprintf(stdout, "[server] Sent %d bytes\n", bytes_sent); @@ -113,9 +113,13 @@ void handle_clients(int sockfd) { free(revents); close(epfd); + /* Close all the file descriptors */ for (size_t i = 0; i < HASHMAP_MAX_CLIENTS; ++i) { close(clients[i].sockfd); + /* TODO: close collisions */ } + + hm_free(clients); } void epoll_ctl_add(int epfd, int sockfd, uint32_t events) {