client: use GSList instead of struct strnode for command lists
Replace a custom data structure with a GLib one.
This commit is contained in:
parent
e5ef2d8a37
commit
90e9079142
56
src/client.c
56
src/client.c
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue