aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--src/gammad.c9
-rw-r--r--src/server.c180
-rw-r--r--src/server.h90
4 files changed, 280 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index db4344f..631b544 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@ COMMAND = gammad
KERNEL = $(shell uname | tr '[A-Z]_' '[a-z]-')
-SRC = filter gammad output ramps util message
+SRC = filter gammad output ramps util message server
OPTIMISE = -Og -g
diff --git a/src/gammad.c b/src/gammad.c
index 7e981ad..6f83021 100644
--- a/src/gammad.c
+++ b/src/gammad.c
@@ -33,6 +33,7 @@
#include "arg.h"
#include "output.h"
#include "util.h"
+#include "server.h"
@@ -452,6 +453,7 @@ int main(int argc, char** argv)
char* pidpath = NULL;
char* socketpath = NULL;
sigset_t mask;
+ int init_stage = 0;
memset(&site, 0, sizeof(site));
@@ -686,6 +688,11 @@ int main(int argc, char** argv)
if (signal(SIGTERM, sig_terminate) == SIG_ERR)
goto fail;
+ /* Initialise the server */
+ if (server_initialise() < 0)
+ goto fail;
+ init_stage++;
+
/* Place in the background unless -f */
if (foreground == 0)
{
@@ -781,6 +788,8 @@ int main(int argc, char** argv)
/* Done */
rc = 0;
done:
+ if (init_stage >= 1)
+ server_destroy(1);
if (socketfd >= 0)
{
shutdown(socketfd, SHUT_RDWR);
diff --git a/src/server.c b/src/server.c
new file mode 100644
index 0000000..843ad81
--- /dev/null
+++ b/src/server.c
@@ -0,0 +1,180 @@
+/**
+ * gammad -- Cooperative gamma server
+ * Copyright (C) 2016 Mattias Andrée (maandree@kth.se)
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "server.h"
+#include "util.h"
+
+#include <sys/socket.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+
+/**
+ * List of all client's file descriptors
+ *
+ * Unused slots, with index less than `connections_used`,
+ * should have the value -1 (negative)
+ */
+int* connections = NULL;
+
+/**
+ * The number of elements allocated for `connections`
+ */
+size_t connections_alloc = 0;
+
+/**
+ * The index of the first unused slot in `connections`
+ */
+size_t connections_ptr = 0;
+
+/**
+ * The index of the last used slot in `connections`, plus 1
+ */
+size_t connections_used = 0;
+
+/**
+ * The server connection's message buffer
+ */
+struct message server_message;
+
+/**
+ * The clients' connections' message buffers
+ */
+struct message* client_messages = NULL;
+
+/**
+ * The server socket's file descriptor
+ */
+extern int socketfd;
+
+
+
+/**
+ * Initialise the state of the connections
+ *
+ * @param Zero on success, -1 on error
+ */
+int server_initialise(void)
+{
+ return message_initialise(&server_message);
+}
+
+
+/**
+ * Destroy the state of the connections
+ *
+ * @param disconnect Disconnect all connections?
+ */
+void server_destroy(int disconnect)
+{
+ size_t i;
+
+ /* TODO */ (void) disconnect;
+
+ for (i = 0; i < connections_used; i++)
+ if (connections[i] >= 0)
+ message_destroy(client_messages + i);
+ free(client_messages);
+ message_destroy(&server_message);
+ free(connections);
+}
+
+
+/**
+ * Marshal the state of the connections
+ *
+ * @param buf Output buffer for the marshalled data,
+ * `NULL` to only measure how many bytes
+ * this buffer needs
+ * @return The number of marshalled bytes
+ */
+size_t server_marshal(void* buf)
+{
+ size_t i, off = 0;
+ char* bs = buf;
+
+ if (bs != NULL)
+ *(size_t*)(bs + off) = connections_ptr;
+ off += sizeof(size_t);
+
+ if (bs != NULL)
+ *(size_t*)(bs + off) = connections_used;
+ off += sizeof(size_t);
+
+ if (bs != NULL)
+ memcpy(bs + off, connections, connections_used * sizeof(*connections));
+ off += connections_used * sizeof(*connections);
+
+ off += message_marshal(&server_message, bs ? bs + off : NULL);
+
+ for (i = 0; i < connections_used; i++)
+ if (connections[i] >= 0)
+ off += message_marshal(client_messages + i, bs ? bs + off : NULL);
+
+ return off;
+}
+
+
+/**
+ * Unmarshal the state of the connections
+ *
+ * @param buf Buffer for the marshalled data
+ * @return The number of unmarshalled bytes, 0 on error
+ */
+size_t server_unmarshal(const void* buf)
+{
+ size_t off = 0, i, n;
+ const char* bs = buf;
+
+ connections = NULL;
+ client_messages = NULL;
+ memset(&server_message, 0, sizeof(server_message));
+
+ connections_ptr = *(const size_t*)(bs + off);
+ off += sizeof(size_t);
+
+ connections_alloc = connections_used = *(const size_t*)(bs + off);
+ off += sizeof(size_t);
+
+ if (connections_alloc > 0)
+ {
+ connections = memdup(bs + off, connections_alloc * sizeof(*connections));
+ if (connections == NULL)
+ return 0;
+ off += connections_used * sizeof(*connections);
+
+ client_messages = malloc(connections_alloc * sizeof(*client_messages));
+ if (client_messages == NULL)
+ return 0;
+ }
+
+ off += n = message_unmarshal(&server_message, bs + off);
+ if (n == 0)
+ return 0;
+
+ for (i = 0; i < connections_used; i++)
+ if (connections[i] >= 0)
+ {
+ off += n = message_unmarshal(client_messages + i, bs ? bs + off : NULL);
+ if (n == 0)
+ return 0;
+ }
+
+ return off;
+}
+
diff --git a/src/server.h b/src/server.h
new file mode 100644
index 0000000..fa5552d
--- /dev/null
+++ b/src/server.h
@@ -0,0 +1,90 @@
+/**
+ * gammad -- Cooperative gamma server
+ * Copyright (C) 2016 Mattias Andrée (maandree@kth.se)
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "message.h"
+
+#include <stddef.h>
+
+
+
+/**
+ * List of all client's file descriptors
+ *
+ * Unused slots, with index less than `connections_used`,
+ * should have the value -1 (negative)
+ */
+extern int* connections;
+
+/**
+ * The number of elements allocated for `connections`
+ */
+extern size_t connections_alloc;
+
+/**
+ * The index of the first unused slot in `connections`
+ */
+extern size_t connections_ptr;
+
+/**
+ * The index of the last used slot in `connections`, plus 1
+ */
+extern size_t connections_used;
+
+/**
+ * The server connection's message buffer
+ */
+extern struct message server_message;
+
+/**
+ * The clients' connections' message buffers
+ */
+extern struct message* client_messages;
+
+
+
+/**
+ * Initialise the state of the connections
+ *
+ * @param Zero on success, -1 on error
+ */
+int server_initialise(void);
+
+/**
+ * Destroy the state of the connections
+ *
+ * @param disconnect Disconnect all connections?
+ */
+void server_destroy(int disconnect);
+
+/**
+ * Marshal the state of the connections
+ *
+ * @param buf Output buffer for the marshalled data,
+ * `NULL` to only measure how many bytes
+ * this buffer needs
+ * @return The number of marshalled bytes
+ */
+size_t server_marshal(void* buf);
+
+/**
+ * Unmarshal the state of the connections
+ *
+ * @param buf Buffer for the marshalled data
+ * @return The number of unmarshalled bytes, 0 on error
+ */
+size_t server_unmarshal(const void* buf);
+