From 90e9079142f533c9a30f3431e03b49bbf4f73a77 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 31 Oct 2008 09:17:56 +0100 Subject: client: use GSList instead of struct strnode for command lists Replace a custom data structure with a GLib one. --- src/client.c | 56 +++++++++++++++----------------------------------------- src/command.c | 13 ++++++------- src/command.h | 4 ++-- 3 files changed, 23 insertions(+), 50 deletions(-) (limited to 'src') diff --git a/src/client.c b/src/client.c index c9123d986..5ee336487 100644 --- a/src/client.c +++ b/src/client.c @@ -31,6 +31,7 @@ #include "../config.h" +#include #include #include #include @@ -70,11 +71,9 @@ struct client { int uid; time_t lastTime; - struct strnode *cmd_list; /* for when in list mode */ - struct strnode *cmd_list_tail; /* for when in list mode */ + GSList *cmd_list; /* for when in list mode */ int cmd_list_OK; /* print OK after each command execution */ size_t cmd_list_size; /* mem cmd_list consumes */ - int cmd_list_dup; /* has the cmd_list been copied to private space? */ struct sllnode *deferred_send; /* for output if client is slow */ size_t deferred_bytes; /* mem deferred_send consumes */ unsigned int num; /* client number */ @@ -132,7 +131,6 @@ static void client_init(struct client *client, int fd) assert(fd >= 0); client->cmd_list_size = 0; - client->cmd_list_dup = 0; client->cmd_list_OK = -1; client->bufferLength = 0; client->bufferPos = 0; @@ -140,7 +138,6 @@ static void client_init(struct client *client, int fd) set_nonblocking(fd); client->lastTime = time(NULL); client->cmd_list = NULL; - client->cmd_list_tail = NULL; client->deferred_send = NULL; client->deferred_bytes = 0; client->num = next_client_num++; @@ -151,42 +148,17 @@ static void client_init(struct client *client, int fd) xwrite(fd, GREETING, strlen(GREETING)); } -static void free_cmd_list(struct strnode *list) +static void free_cmd_list(GSList *list) { - struct strnode *tmp = list; + for (GSList *tmp = list; tmp != NULL; tmp = g_slist_next(tmp)) + g_free(tmp->data); - while (tmp) { - struct strnode *next = tmp->next; - free(tmp); - tmp = next; - } -} - -static void cmd_list_clone(struct client *client) -{ - struct strnode *new = dup_strlist(client->cmd_list); - free_cmd_list(client->cmd_list); - client->cmd_list = new; - client->cmd_list_dup = 1; - - /* new tail */ - while (new && new->next) - new = new->next; - client->cmd_list_tail = new; + g_slist_free(list); } -static void new_cmd_list_ptr(struct client *client, char *s, const int size) +static void new_cmd_list_ptr(struct client *client, char *s) { - struct strnode *new; - - /* allocate from the heap */ - new = client->cmd_list_dup ? new_strnode_dup(s, size) - : new_strnode(s); - if (client->cmd_list) { - client->cmd_list_tail->next = new; - client->cmd_list_tail = new; - } else - client->cmd_list = client->cmd_list_tail = new; + client->cmd_list = g_slist_prepend(client->cmd_list, g_strdup(s)); } static void client_close(struct client *client) @@ -308,6 +280,12 @@ static int client_process_line(struct client *client, char *line) if (strcmp(line, CLIENT_LIST_MODE_END) == 0) { DEBUG("client %i: process command " "list\n", client->num); + + /* for scalability reasons, we have prepended + each new command; now we have to reverse it + to restore the correct order */ + client->cmd_list = g_slist_reverse(client->cmd_list); + ret = command_process_list(client, client->cmd_list_OK, client->cmd_list); @@ -340,7 +318,7 @@ static int client_process_line(struct client *client, char *line) client_max_command_list_size); return COMMAND_RETURN_CLOSE; } else - new_cmd_list_ptr(client, line, len); + new_cmd_list_ptr(client, line); } } else { if (strcmp(line, CLIENT_LIST_MODE_BEGIN) == 0) { @@ -411,10 +389,6 @@ static int client_input_received(struct client *client, size_t bytesRead) client->num); return COMMAND_RETURN_CLOSE; } - if (client->cmd_list_OK >= 0 && - client->cmd_list && - !client->cmd_list_dup) - cmd_list_clone(client); assert(client->bufferLength >= client->bufferPos && "bufferLength >= bufferPos"); client->bufferLength -= client->bufferPos; diff --git a/src/command.c b/src/command.c index 9619355f6..452568238 100644 --- a/src/command.c +++ b/src/command.c @@ -31,7 +31,6 @@ #include "log.h" #include "utils.h" #include "stored_playlist.h" -#include "sllist.h" #include "ack.h" #include "audio.h" #include "dbUtils.h" @@ -1497,24 +1496,24 @@ command_process(struct client *client, char *commandString) enum command_return command_process_list(struct client *client, - bool list_ok, struct strnode *list) + bool list_ok, GSList *list) { - struct strnode *cur = list; enum command_return ret = COMMAND_RETURN_OK; command_list_num = 0; - while (cur) { + for (GSList *cur = list; cur != NULL; cur = g_slist_next(cur)) { + char *cmd = cur->data; + DEBUG("command_process_list: process command \"%s\"\n", - cur->data); - ret = command_process(client, cur->data); + cmd); + ret = command_process(client, cmd); DEBUG("command_process_list: command returned %i\n", ret); if (ret != COMMAND_RETURN_OK || client_is_expired(client)) break; else if (list_ok) client_puts(client, "list_OK\n"); command_list_num++; - cur = cur->next; } command_list_num = 0; diff --git a/src/command.h b/src/command.h index 763487c12..bcefd0376 100644 --- a/src/command.h +++ b/src/command.h @@ -20,9 +20,9 @@ #define COMMAND_H #include "gcc.h" -#include "sllist.h" #include "ack.h" +#include #include enum command_return { @@ -40,7 +40,7 @@ void command_finish(void); enum command_return command_process_list(struct client *client, - bool list_ok, struct strnode *list); + bool list_ok, GSList *list); enum command_return command_process(struct client *client, char *commandString); -- cgit v1.2.3