client: use GSList instead of struct strnode for command lists

Replace a custom data structure with a GLib one.
This commit is contained in:
Max Kellermann 2008-10-31 09:17:56 +01:00
parent e5ef2d8a37
commit 90e9079142
3 changed files with 23 additions and 50 deletions

View File

@ -31,6 +31,7 @@
#include "../config.h" #include "../config.h"
#include <glib.h>
#include <assert.h> #include <assert.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
@ -70,11 +71,9 @@ struct client {
int uid; int uid;
time_t lastTime; time_t lastTime;
struct strnode *cmd_list; /* for when in list mode */ GSList *cmd_list; /* for when in list mode */
struct strnode *cmd_list_tail; /* for when in list mode */
int cmd_list_OK; /* print OK after each command execution */ int cmd_list_OK; /* print OK after each command execution */
size_t cmd_list_size; /* mem cmd_list consumes */ 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 */ struct sllnode *deferred_send; /* for output if client is slow */
size_t deferred_bytes; /* mem deferred_send consumes */ size_t deferred_bytes; /* mem deferred_send consumes */
unsigned int num; /* client number */ unsigned int num; /* client number */
@ -132,7 +131,6 @@ static void client_init(struct client *client, int fd)
assert(fd >= 0); assert(fd >= 0);
client->cmd_list_size = 0; client->cmd_list_size = 0;
client->cmd_list_dup = 0;
client->cmd_list_OK = -1; client->cmd_list_OK = -1;
client->bufferLength = 0; client->bufferLength = 0;
client->bufferPos = 0; client->bufferPos = 0;
@ -140,7 +138,6 @@ static void client_init(struct client *client, int fd)
set_nonblocking(fd); set_nonblocking(fd);
client->lastTime = time(NULL); client->lastTime = time(NULL);
client->cmd_list = NULL; client->cmd_list = NULL;
client->cmd_list_tail = NULL;
client->deferred_send = NULL; client->deferred_send = NULL;
client->deferred_bytes = 0; client->deferred_bytes = 0;
client->num = next_client_num++; client->num = next_client_num++;
@ -151,42 +148,17 @@ static void client_init(struct client *client, int fd)
xwrite(fd, GREETING, strlen(GREETING)); 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) { g_slist_free(list);
struct strnode *next = tmp->next;
free(tmp);
tmp = next;
}
} }
static void cmd_list_clone(struct client *client) static void new_cmd_list_ptr(struct client *client, char *s)
{ {
struct strnode *new = dup_strlist(client->cmd_list); client->cmd_list = g_slist_prepend(client->cmd_list, g_strdup(s));
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;
}
static void new_cmd_list_ptr(struct client *client, char *s, const int size)
{
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;
} }
static void client_close(struct client *client) 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) { if (strcmp(line, CLIENT_LIST_MODE_END) == 0) {
DEBUG("client %i: process command " DEBUG("client %i: process command "
"list\n", client->num); "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, ret = command_process_list(client,
client->cmd_list_OK, client->cmd_list_OK,
client->cmd_list); client->cmd_list);
@ -340,7 +318,7 @@ static int client_process_line(struct client *client, char *line)
client_max_command_list_size); client_max_command_list_size);
return COMMAND_RETURN_CLOSE; return COMMAND_RETURN_CLOSE;
} else } else
new_cmd_list_ptr(client, line, len); new_cmd_list_ptr(client, line);
} }
} else { } else {
if (strcmp(line, CLIENT_LIST_MODE_BEGIN) == 0) { 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); client->num);
return COMMAND_RETURN_CLOSE; 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 assert(client->bufferLength >= client->bufferPos
&& "bufferLength >= bufferPos"); && "bufferLength >= bufferPos");
client->bufferLength -= client->bufferPos; client->bufferLength -= client->bufferPos;

View File

@ -31,7 +31,6 @@
#include "log.h" #include "log.h"
#include "utils.h" #include "utils.h"
#include "stored_playlist.h" #include "stored_playlist.h"
#include "sllist.h"
#include "ack.h" #include "ack.h"
#include "audio.h" #include "audio.h"
#include "dbUtils.h" #include "dbUtils.h"
@ -1497,24 +1496,24 @@ command_process(struct client *client, char *commandString)
enum command_return enum command_return
command_process_list(struct client *client, 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; enum command_return ret = COMMAND_RETURN_OK;
command_list_num = 0; 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", DEBUG("command_process_list: process command \"%s\"\n",
cur->data); cmd);
ret = command_process(client, cur->data); ret = command_process(client, cmd);
DEBUG("command_process_list: command returned %i\n", ret); DEBUG("command_process_list: command returned %i\n", ret);
if (ret != COMMAND_RETURN_OK || client_is_expired(client)) if (ret != COMMAND_RETURN_OK || client_is_expired(client))
break; break;
else if (list_ok) else if (list_ok)
client_puts(client, "list_OK\n"); client_puts(client, "list_OK\n");
command_list_num++; command_list_num++;
cur = cur->next;
} }
command_list_num = 0; command_list_num = 0;

View File

@ -20,9 +20,9 @@
#define COMMAND_H #define COMMAND_H
#include "gcc.h" #include "gcc.h"
#include "sllist.h"
#include "ack.h" #include "ack.h"
#include <glib.h>
#include <stdbool.h> #include <stdbool.h>
enum command_return { enum command_return {
@ -40,7 +40,7 @@ void command_finish(void);
enum command_return enum command_return
command_process_list(struct client *client, command_process_list(struct client *client,
bool list_ok, struct strnode *list); bool list_ok, GSList *list);
enum command_return enum command_return
command_process(struct client *client, char *commandString); command_process(struct client *client, char *commandString);