aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO14
-rw-r--r--src/mds-registry/globals.h2
-rw-r--r--src/mds-registry/reexec.c56
-rw-r--r--src/mds-registry/slave.c27
-rw-r--r--src/mds-registry/slave.h8
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 <libmdsserver/macros.h>
#include <libmdsserver/hash-help.h>
@@ -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(&reg_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(&reg_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
@@ -112,6 +112,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
*
* @param wait_set Set of protocols for which to wait that they become available
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
@@ -84,6 +84,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
*
* @param client The client's ID