diff options
-rw-r--r-- | src/libmdsserver/hash-table.c | 24 | ||||
-rw-r--r-- | src/libmdsserver/hash-table.h | 9 | ||||
-rw-r--r-- | src/mds-echo.c | 14 | ||||
-rw-r--r-- | src/mds-registry.c | 146 | ||||
-rw-r--r-- | src/mds-registry.h | 14 |
5 files changed, 163 insertions, 44 deletions
diff --git a/src/libmdsserver/hash-table.c b/src/libmdsserver/hash-table.c index ab78f0a..dac9303 100644 --- a/src/libmdsserver/hash-table.c +++ b/src/libmdsserver/hash-table.c @@ -247,6 +247,30 @@ size_t hash_table_get(const hash_table_t* restrict this, size_t key) /** + * Look up an entry in the table + * + * @param this The hash table + * @param key The key associated with the value + * @return The entry associated with the key, `NULL` if the key was not used + */ +hash_entry_t* hash_table_get_entry(const hash_table_t* restrict this, size_t key) +{ + size_t key_hash = hash(this, key); + size_t index = truncate_hash(this, key_hash); + hash_entry_t* restrict bucket = this->buckets[index]; + + while (bucket) + { + if (TEST_KEY(this, bucket, key, key_hash)) + return bucket; + bucket = bucket->next; + } + + return NULL; +} + + +/** * Add an entry to the table * * @param this The hash table diff --git a/src/libmdsserver/hash-table.h b/src/libmdsserver/hash-table.h index 9a84db2..edf8d3a 100644 --- a/src/libmdsserver/hash-table.h +++ b/src/libmdsserver/hash-table.h @@ -184,6 +184,15 @@ int hash_table_contains_key(const hash_table_t* restrict this, size_t key) __att size_t hash_table_get(const hash_table_t* restrict this, size_t key); /** + * Look up an entry in the table + * + * @param this The hash table + * @param key The key associated with the value + * @return The entry associated with the key, `NULL` if the key was not used + */ +hash_entry_t* hash_table_get_entry(const hash_table_t* restrict this, size_t key); + +/** * Add an entry to the table * * @param this The hash table diff --git a/src/mds-echo.c b/src/mds-echo.c index 0f05e25..4295816 100644 --- a/src/mds-echo.c +++ b/src/mds-echo.c @@ -159,6 +159,8 @@ int marshal_server(char* state_buf) buf_set_next(state_buf, int, connected); buf_set_next(state_buf, int32_t, message_id); mds_message_marshal(&received, state_buf); + + mds_message_destroy(&received); return 0; } @@ -206,6 +208,8 @@ int __attribute__((const)) reexec_failure_recover(void) */ int master_loop(void) { + int rc = 1; + while (!reexecing && !terminating) { int r = mds_message_read(&received, socket_fd); @@ -235,15 +239,15 @@ int master_loop(void) connected = 1; } - mds_message_destroy(&received); - free(echo_buffer); - return 0; + rc = 0; + goto fail; pfail: perror(*argv); fail: - mds_message_destroy(&received); + if (rc || !reexecing) + mds_message_destroy(&received); free(echo_buffer); - return 1; + return rc; } diff --git a/src/mds-registry.c b/src/mds-registry.c index c7ac518..83702a1 100644 --- a/src/mds-registry.c +++ b/src/mds-registry.c @@ -187,7 +187,9 @@ int postinitialise_server(void) */ size_t marshal_server_size(void) { - return 2 * sizeof(int) + sizeof(int32_t) + mds_message_marshal_size(&received); + size_t rc = 2 * sizeof(int) + sizeof(int32_t) + sizeof(size_t); + rc += mds_message_marshal_size(&received); + return rc; } @@ -199,10 +201,17 @@ size_t marshal_server_size(void) */ int marshal_server(char* state_buf) { + size_t n = mds_message_marshal_size(&received); buf_set_next(state_buf, int, MDS_REGISTRY_VARS_VERSION); buf_set_next(state_buf, int, connected); buf_set_next(state_buf, int32_t, message_id); + buf_set_next(state_buf, size_t, n); mds_message_marshal(&received, state_buf); + state_buf += n / sizeof(char); + /* TODO marshal ®_table */ + + hash_table_destroy(®_table, (free_func*)reg_table_free_key, (free_func*)reg_table_free_value); + mds_message_destroy(&received); return 0; } @@ -219,18 +228,22 @@ int marshal_server(char* state_buf) */ int unmarshal_server(char* state_buf) { - int r; + int r, rc = 0; + size_t n; /* buf_get_next(state_buf, int, MDS_REGISTRY_VARS_VERSION); */ buf_next(state_buf, int, 1); buf_get_next(state_buf, int, connected); buf_get_next(state_buf, int32_t, message_id); - r = mds_message_unmarshal(&received, state_buf); + buf_get_next(state_buf, size_t, n); + rc |= r = mds_message_unmarshal(&received, state_buf); if (r) mds_message_destroy(&received); + state_buf += n / sizeof(char); /* TODO unmarshal ®_table */ + reg_table.key_comparator = (compare_func*)string_comparator; reg_table.hasher = (hash_func*)string_hash; - return r; + return rc; } @@ -291,11 +304,11 @@ int master_loop(void) fail: if (rc || !reexecing) { - /* TODO cleanup reg_table */ + hash_table_destroy(®_table, (free_func*)reg_table_free_key, (free_func*)reg_table_free_value); + mds_message_destroy(&received); } pthread_mutex_destroy(®_mutex); pthread_cond_destroy(®_cond); - mds_message_destroy(&received); free(send_buffer); return rc; } @@ -459,50 +472,80 @@ int registry_action(size_t length, int action, const char* recv_client_id, const begin += len + 1; if (action == 1) - if (hash_table_contains_key(®_table, command_key)) - { - size_t address = hash_table_get(®_table, command_key); - client_list_t* list = (client_list_t*)(void*)address; - if (client_list_add(list, client) < 0) - { - pthread_mutex_unlock(®_mutex); - return -1; - } - } - else - { - client_list_t* list = malloc(sizeof(client_list_t)); - void* address = list; - if (list == NULL) - { - perror(*argv); - pthread_mutex_unlock(®_mutex); - return -1; - } - if (client_list_create(list, 1) || - client_list_add(list, client) || - (hash_table_put(®_table, command_key, (size_t)address) == 0)) - { - perror(*argv); - client_list_destroy(list); - free(list); - pthread_mutex_unlock(®_mutex); - return -1; - } - } + { + if (hash_table_contains_key(®_table, command_key)) + { + size_t address = hash_table_get(®_table, command_key); + client_list_t* list = (client_list_t*)(void*)address; + if (client_list_add(list, client) < 0) + { + perror(*argv); + pthread_mutex_unlock(®_mutex); + return -1; + } + } + else + { + client_list_t* list = malloc(sizeof(client_list_t)); + void* address = list; + if (list == NULL) + { + perror(*argv); + pthread_mutex_unlock(®_mutex); + return -1; + } + if ((command = strdup(command)) == NULL) + { + perror(*argv); + free(list); + pthread_mutex_unlock(®_mutex); + return -1; + } + command_key = (size_t)(void*)command; + if (client_list_create(list, 1) || + client_list_add(list, client) || + (hash_table_put(®_table, command_key, (size_t)address) == 0)) + { + perror(*argv); + client_list_destroy(list); + free(list); + free(command); + pthread_mutex_unlock(®_mutex); + return -1; + } + } + } else if ((action == -1) && hash_table_contains_key(®_table, command_key)) { - size_t address = hash_table_get(®_table, command_key); + hash_entry_t* entry = hash_table_get_entry(®_table, command_key); + size_t address = entry->value; client_list_t* list = (client_list_t*)(void*)address; client_list_remove(list, client); + if (list->size == 0) + { + client_list_destroy(list); + free(list); + hash_table_remove(®_table, command_key); + reg_table_free_key(entry->key); + } } else if ((action == 0) && !hash_table_contains_key(®_table, command_key)) { + if ((command = strdup(command)) == NULL) + { + perror(*argv); + hash_table_destroy(wait_set, (free_func*)reg_table_free_key, NULL); + free(wait_set); + pthread_mutex_unlock(®_mutex); + return -1; + } + command_key = (size_t)(void*)command; if (hash_table_put(wait_set, command_key, 1) == 0) if (errno) { perror(*argv); - hash_table_destroy(wait_set, NULL, NULL); + free(command); + hash_table_destroy(wait_set, (free_func*)reg_table_free_key, NULL); free(wait_set); pthread_mutex_unlock(®_mutex); return -1; @@ -608,6 +651,31 @@ int list_registry(const char* recv_client_id, const char* recv_message_id) /** + * Free a key from a table + * + * @param obj The key + */ +void reg_table_free_key(size_t obj) +{ + char* command = (char*)(void*)obj; + free(command); +} + + +/** + * Free a value from a table + * + * @param obj The value + */ +void reg_table_free_value(size_t obj) +{ + client_list_t* list = (client_list_t*)(void*)obj; + client_list_destroy(list); + free(list); +} + + +/** * Send a full message even if interrupted * * @param message The message to send diff --git a/src/mds-registry.h b/src/mds-registry.h index c8ced44..6eb09b4 100644 --- a/src/mds-registry.h +++ b/src/mds-registry.h @@ -54,6 +54,20 @@ int registry_action(size_t length, int action, const char* recv_client_id, const int list_registry(const char* recv_client_id, const char* recv_message_id); /** + * Free a key from a table + * + * @param obj The key + */ +void reg_table_free_key(size_t obj); + +/** + * Free a value from a table + * + * @param obj The value + */ +void reg_table_free_value(size_t obj); + +/** * Send a full message even if interrupted * * @param message The message to send |