aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libmdsserver/hash-table.c24
-rw-r--r--src/libmdsserver/hash-table.h9
-rw-r--r--src/mds-echo.c14
-rw-r--r--src/mds-registry.c146
-rw-r--r--src/mds-registry.h14
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 &reg_table */
+
+ hash_table_destroy(&reg_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 &reg_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(&reg_table, (free_func*)reg_table_free_key, (free_func*)reg_table_free_value);
+ mds_message_destroy(&received);
}
pthread_mutex_destroy(&reg_mutex);
pthread_cond_destroy(&reg_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(&reg_table, command_key))
- {
- size_t address = hash_table_get(&reg_table, command_key);
- client_list_t* list = (client_list_t*)(void*)address;
- if (client_list_add(list, client) < 0)
- {
- pthread_mutex_unlock(&reg_mutex);
- return -1;
- }
- }
- else
- {
- client_list_t* list = malloc(sizeof(client_list_t));
- void* address = list;
- if (list == NULL)
- {
- perror(*argv);
- pthread_mutex_unlock(&reg_mutex);
- return -1;
- }
- if (client_list_create(list, 1) ||
- client_list_add(list, client) ||
- (hash_table_put(&reg_table, command_key, (size_t)address) == 0))
- {
- perror(*argv);
- client_list_destroy(list);
- free(list);
- pthread_mutex_unlock(&reg_mutex);
- return -1;
- }
- }
+ {
+ if (hash_table_contains_key(&reg_table, command_key))
+ {
+ size_t address = hash_table_get(&reg_table, command_key);
+ client_list_t* list = (client_list_t*)(void*)address;
+ if (client_list_add(list, client) < 0)
+ {
+ perror(*argv);
+ pthread_mutex_unlock(&reg_mutex);
+ return -1;
+ }
+ }
+ else
+ {
+ client_list_t* list = malloc(sizeof(client_list_t));
+ void* address = list;
+ if (list == NULL)
+ {
+ perror(*argv);
+ pthread_mutex_unlock(&reg_mutex);
+ return -1;
+ }
+ if ((command = strdup(command)) == NULL)
+ {
+ perror(*argv);
+ free(list);
+ pthread_mutex_unlock(&reg_mutex);
+ return -1;
+ }
+ command_key = (size_t)(void*)command;
+ if (client_list_create(list, 1) ||
+ client_list_add(list, client) ||
+ (hash_table_put(&reg_table, command_key, (size_t)address) == 0))
+ {
+ perror(*argv);
+ client_list_destroy(list);
+ free(list);
+ free(command);
+ pthread_mutex_unlock(&reg_mutex);
+ return -1;
+ }
+ }
+ }
else if ((action == -1) && hash_table_contains_key(&reg_table, command_key))
{
- size_t address = hash_table_get(&reg_table, command_key);
+ hash_entry_t* entry = hash_table_get_entry(&reg_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(&reg_table, command_key);
+ reg_table_free_key(entry->key);
+ }
}
else if ((action == 0) && !hash_table_contains_key(&reg_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(&reg_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(&reg_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