From 70c2d0af540ecc44a104abb034ee5ff1c910dd48 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Sat, 2 Aug 2014 21:34:22 +0200 Subject: mds-registry: marshal and unmarshal the slave list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- TODO | 14 +++++++++--- src/mds-registry/globals.h | 2 +- src/mds-registry/reexec.c | 56 +++++++++++++++++++++++++++++++++++++++++++++- src/mds-registry/slave.c | 27 ++++++++++++++++++++++ src/mds-registry/slave.h | 8 +++++++ 5 files changed, 102 insertions(+), 5 deletions(-) diff --git a/TODO b/TODO index 6bf4e34..1762f29 100644 --- a/TODO +++ b/TODO @@ -26,8 +26,8 @@ Missing servers: drag Drag and drop cursorshadow Decorate cursors with shadows kill Kill processes based on their windows - shm Network enabled shared memory - sem Network enabled shared semaphores + shm Network enabled SysV shared memory + sem Network enabled SysV semaphore arrays focus Focuses the selected window colour Mapping of colour by name (system colours) and value state Keeps track of windows' states @@ -36,8 +36,16 @@ Missing servers: stack A simple, reference implementation of a, stack window manager workspace A simple, reference implementation of a, workspaces vt VT switcher + +Missing commands: + cmd-registry Command line interface for the protocol registry + conf Command line interface for reconfiguring servers + +Need testing: + + registry Fast lanes -Optimise use of mutexe +Optimise use of mutexe with shared and exclusive locks diff --git a/src/mds-registry/globals.h b/src/mds-registry/globals.h index dcbf91d..76f9c91 100644 --- a/src/mds-registry/globals.h +++ b/src/mds-registry/globals.h @@ -75,7 +75,7 @@ extern size_t running_slaves; /** * List of running slaves */ -extern linked_list_t slave_list; /* TODO (un)marshal */ +extern linked_list_t slave_list; /** * Mutex for slave data diff --git a/src/mds-registry/reexec.c b/src/mds-registry/reexec.c index 9bee27b..6e34db8 100644 --- a/src/mds-registry/reexec.c +++ b/src/mds-registry/reexec.c @@ -19,6 +19,7 @@ #include "util.h" #include "globals.h" +#include "slave.h" #include #include @@ -41,10 +42,12 @@ */ size_t marshal_server_size(void) { - size_t i, rc = 2 * sizeof(int) + sizeof(int32_t) + 3 * sizeof(size_t); + size_t i, rc = 2 * sizeof(int) + sizeof(int32_t) + 4 * sizeof(size_t); hash_entry_t* entry; + ssize_t node; rc += mds_message_marshal_size(&received); + rc += linked_list_marshal_size(&slave_list); foreach_hash_table_entry (reg_table, i, entry) { @@ -55,6 +58,12 @@ size_t marshal_server_size(void) rc += len + sizeof(size_t) + client_list_marshal_size(list); } + foreach_linked_list_node (slave_list, node) + { + slave_t* slave = (slave_t*)(void*)slave_list.values[node]; + rc += slave_marshal_size(slave); + } + return rc; } @@ -69,6 +78,7 @@ int marshal_server(char* state_buf) { size_t i, n = mds_message_marshal_size(&received); hash_entry_t* entry; + ssize_t node; buf_set_next(state_buf, int, MDS_REGISTRY_VARS_VERSION); buf_set_next(state_buf, int, connected); @@ -94,8 +104,21 @@ int marshal_server(char* state_buf) state_buf += n / sizeof(char); } + n = linked_list_marshal_size(&slave_list); + buf_set_next(state_buf, size_t, n); + linked_list_marshal(&slave_list, state_buf); + state_buf += n / sizeof(char); + + foreach_linked_list_node (slave_list, node) + { + slave_t* slave = (slave_t*)(void*)(slave_list.values[node]); + state_buf += slave_marshal(slave, state_buf) / sizeof(char); + slave_destroy(slave); + } + hash_table_destroy(®_table, (free_func*)reg_table_free_key, (free_func*)reg_table_free_value); mds_message_destroy(&received); + linked_list_destroy(&slave_list); return 0; } @@ -114,7 +137,9 @@ int unmarshal_server(char* state_buf) { char* command; client_list_t* list; + slave_t* slave; size_t i, n, m; + ssize_t node; int stage = 0; /* buf_get_next(state_buf, int, MDS_REGISTRY_VARS_VERSION); */ @@ -145,10 +170,32 @@ int unmarshal_server(char* state_buf) hash_table_put(®_table, (size_t)(void*)command, (size_t)(void*)list); fail_if (errno); } + command = NULL; + stage = 4; reg_table.key_comparator = (compare_func*)string_comparator; reg_table.hasher = (hash_func*)string_hash; + buf_get_next(state_buf, size_t, n); + fail_if (linked_list_unmarshal(&slave_list, state_buf)); + state_buf += n / sizeof(char); + + foreach_linked_list_node (slave_list, node) + { + stage = 5; + fail_if ((slave = malloc(sizeof(slave_t))) == NULL); + stage = 6; + fail_if ((n = slave_unmarshal(slave, state_buf)) == 0); + state_buf += n / sizeof(char); + slave_list.values[node] = (size_t)(void*)slave; + } + + foreach_linked_list_node (slave_list, node) + { + slave = (slave_t*)(void*)(slave_list.values[node]); + fail_if (start_created_slave(slave)); + } + return 0; pfail: xperror(*argv); @@ -162,6 +209,13 @@ int unmarshal_server(char* state_buf) client_list_destroy(list); free(list); } + if (stage >= 5) + linked_list_destroy(&slave_list); + if (stage >= 6) + { + slave_destroy(slave); + free(slave); + } abort(); return -1; } diff --git a/src/mds-registry/slave.c b/src/mds-registry/slave.c index 6c5406d..27d054a 100644 --- a/src/mds-registry/slave.c +++ b/src/mds-registry/slave.c @@ -111,6 +111,33 @@ static void* slave_loop(void* data) } +/** + * Start a slave thread with an already created slave + * + * @param slave The slave + * @return Non-zero on error, `errno` will be set accordingly + */ +int start_created_slave(slave_t* restrict slave) +{ + if ((errno = pthread_mutex_lock(&slave_mutex))) + return -1; + + if ((errno = pthread_create(&(slave->thread), NULL, slave_loop, (void*)(intptr_t)slave))) + { + pthread_mutex_unlock(&slave_mutex); + return -1; + } + + if ((errno = pthread_detach(slave->thread))) + xperror(*argv); + + running_slaves++; + pthread_mutex_unlock(&slave_mutex); + + return 0; +} + + /** * Start a slave thread * diff --git a/src/mds-registry/slave.h b/src/mds-registry/slave.h index ae8ae09..cd98f80 100644 --- a/src/mds-registry/slave.h +++ b/src/mds-registry/slave.h @@ -83,6 +83,14 @@ typedef struct slave /* TODO: add time-to-live */ */ int start_slave(hash_table_t* restrict wait_set, const char* restrict recv_client_id, const char* restrict recv_message_id); +/** + * Start a slave thread with an already created slave + * + * @param slave The slave + * @return Non-zero on error, `errno` will be set accordingly + */ +int start_created_slave(slave_t* restrict slave); + /** * Close all slaves associated with a client * -- cgit v1.2.3-70-g09d2