[mpd] Use generic inter thread commands util
This commit is contained in:
parent
9856536fd7
commit
4aacf487e8
161
src/mpd.c
161
src/mpd.c
|
@ -62,6 +62,7 @@
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
#include "filescanner.h"
|
#include "filescanner.h"
|
||||||
|
#include "commands.h"
|
||||||
|
|
||||||
|
|
||||||
static pthread_t tid_mpd;
|
static pthread_t tid_mpd;
|
||||||
|
@ -70,29 +71,12 @@ static struct event_base *evbase_mpd;
|
||||||
static int g_exit_pipe[2];
|
static int g_exit_pipe[2];
|
||||||
static struct event *g_exitev;
|
static struct event *g_exitev;
|
||||||
|
|
||||||
static int g_cmd_pipe[2];
|
static struct commands_base *cmdbase;
|
||||||
static struct event *g_cmdev;
|
|
||||||
|
|
||||||
static struct evhttp *evhttpd;
|
static struct evhttp *evhttpd;
|
||||||
|
|
||||||
struct evconnlistener *listener;
|
struct evconnlistener *listener;
|
||||||
|
|
||||||
struct mpd_command;
|
|
||||||
|
|
||||||
typedef int (*cmd_func)(struct mpd_command *cmd);
|
|
||||||
|
|
||||||
struct mpd_command
|
|
||||||
{
|
|
||||||
pthread_mutex_t lck;
|
|
||||||
pthread_cond_t cond;
|
|
||||||
|
|
||||||
cmd_func func;
|
|
||||||
|
|
||||||
enum listener_event_type arg_evtype;
|
|
||||||
int nonblock;
|
|
||||||
|
|
||||||
int ret;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define COMMAND_ARGV_MAX 37
|
#define COMMAND_ARGV_MAX 37
|
||||||
|
|
||||||
|
@ -207,40 +191,6 @@ struct idle_client
|
||||||
|
|
||||||
struct idle_client *idle_clients;
|
struct idle_client *idle_clients;
|
||||||
|
|
||||||
/* ---------------------------- COMMAND EXECUTION -------------------------- */
|
|
||||||
|
|
||||||
static int
|
|
||||||
send_command(struct mpd_command *cmd)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!cmd->func)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_MPD, "BUG: cmd->func is NULL!\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = write(g_cmd_pipe[1], &cmd, sizeof(cmd));
|
|
||||||
if (ret != sizeof(cmd))
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_MPD, "Could not send command: %s\n", strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
nonblock_command(struct mpd_command *cmd)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = send_command(cmd);
|
|
||||||
if (ret < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
thread_exit(void)
|
thread_exit(void)
|
||||||
|
@ -3699,7 +3649,7 @@ mpd_command_decoders(struct evbuffer *evbuf, int argc, char **argv, char **errms
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct command
|
struct mpd_command
|
||||||
{
|
{
|
||||||
/* The command name */
|
/* The command name */
|
||||||
const char *mpdcommand;
|
const char *mpdcommand;
|
||||||
|
@ -3716,7 +3666,7 @@ struct command
|
||||||
int (*handler)(struct evbuffer *evbuf, int argc, char **argv, char **errmsg);
|
int (*handler)(struct evbuffer *evbuf, int argc, char **argv, char **errmsg);
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct command mpd_handlers[] =
|
static struct mpd_command mpd_handlers[] =
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Commands for querying status
|
* Commands for querying status
|
||||||
|
@ -4192,7 +4142,7 @@ static struct command mpd_handlers[] =
|
||||||
* @param name the name of the command
|
* @param name the name of the command
|
||||||
* @return the command or NULL if it is an unknown/unsupported command
|
* @return the command or NULL if it is an unknown/unsupported command
|
||||||
*/
|
*/
|
||||||
static struct command*
|
static struct mpd_command*
|
||||||
mpd_find_command(const char *name)
|
mpd_find_command(const char *name)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -4240,7 +4190,7 @@ mpd_read_cb(struct bufferevent *bev, void *ctx)
|
||||||
int ncmd;
|
int ncmd;
|
||||||
char *line;
|
char *line;
|
||||||
char *errmsg;
|
char *errmsg;
|
||||||
struct command *command;
|
struct mpd_command *command;
|
||||||
enum command_list_type listtype;
|
enum command_list_type listtype;
|
||||||
int idle_cmd;
|
int idle_cmd;
|
||||||
int close_cmd;
|
int close_cmd;
|
||||||
|
@ -4525,16 +4475,18 @@ mpd_notify_idle_client(struct idle_client *client, enum listener_event_type type
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static enum command_state
|
||||||
mpd_notify_idle(struct mpd_command *cmd)
|
mpd_notify_idle(void *arg, int *retval)
|
||||||
{
|
{
|
||||||
|
enum listener_event_type type;
|
||||||
struct idle_client *client;
|
struct idle_client *client;
|
||||||
struct idle_client *prev;
|
struct idle_client *prev;
|
||||||
struct idle_client *next;
|
struct idle_client *next;
|
||||||
int i;
|
int i;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_MPD, "Notify clients waiting for idle results: %d\n", cmd->arg_evtype);
|
type = *(enum listener_event_type *)arg;
|
||||||
|
DPRINTF(E_DBG, L_MPD, "Notify clients waiting for idle results: %d\n", type);
|
||||||
|
|
||||||
prev = NULL;
|
prev = NULL;
|
||||||
next = NULL;
|
next = NULL;
|
||||||
|
@ -4546,7 +4498,7 @@ mpd_notify_idle(struct mpd_command *cmd)
|
||||||
|
|
||||||
next = client->next;
|
next = client->next;
|
||||||
|
|
||||||
ret = mpd_notify_idle_client(client, cmd->arg_evtype);
|
ret = mpd_notify_idle_client(client, type);
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
{
|
{
|
||||||
|
@ -4566,63 +4518,20 @@ mpd_notify_idle(struct mpd_command *cmd)
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
*retval = 0;
|
||||||
|
return COMMAND_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mpd_listener_cb(enum listener_event_type type)
|
mpd_listener_cb(enum listener_event_type type)
|
||||||
{
|
{
|
||||||
|
enum listener_event_type *ptr;
|
||||||
|
|
||||||
|
ptr = (enum listener_event_type *)malloc(sizeof(enum listener_event_type));
|
||||||
|
*ptr = type;
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_MPD, "Listener callback called with event type %d.\n", type);
|
DPRINTF(E_DBG, L_MPD, "Listener callback called with event type %d.\n", type);
|
||||||
struct mpd_command *cmd;
|
commands_exec_async(cmdbase, mpd_notify_idle, ptr);
|
||||||
|
|
||||||
cmd = (struct mpd_command *)malloc(sizeof(struct mpd_command));
|
|
||||||
if (!cmd)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_MPD, "Could not allocate cache_command\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(cmd, 0, sizeof(struct mpd_command));
|
|
||||||
|
|
||||||
cmd->nonblock = 1;
|
|
||||||
|
|
||||||
cmd->func = mpd_notify_idle;
|
|
||||||
cmd->arg_evtype = type;
|
|
||||||
|
|
||||||
nonblock_command(cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
command_cb(int fd, short what, void *arg)
|
|
||||||
{
|
|
||||||
struct mpd_command *cmd;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = read(g_cmd_pipe[0], &cmd, sizeof(cmd));
|
|
||||||
if (ret != sizeof(cmd))
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_MPD, "Could not read command! (read %d): %s\n", ret, (ret < 0) ? strerror(errno) : "-no error-");
|
|
||||||
goto readd;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd->nonblock)
|
|
||||||
{
|
|
||||||
cmd->func(cmd);
|
|
||||||
|
|
||||||
free(cmd);
|
|
||||||
goto readd;
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_lock(&cmd->lck);
|
|
||||||
|
|
||||||
ret = cmd->func(cmd);
|
|
||||||
cmd->ret = ret;
|
|
||||||
|
|
||||||
pthread_cond_signal(&cmd->cond);
|
|
||||||
pthread_mutex_unlock(&cmd->lck);
|
|
||||||
|
|
||||||
readd:
|
|
||||||
event_add(g_cmdev, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -4772,17 +4681,6 @@ int mpd_init(void)
|
||||||
goto exit_fail;
|
goto exit_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_PIPE2
|
|
||||||
ret = pipe2(g_cmd_pipe, O_CLOEXEC);
|
|
||||||
#else
|
|
||||||
ret = pipe(g_cmd_pipe);
|
|
||||||
#endif
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_MPD, "Could not create command pipe: %s\n", strerror(errno));
|
|
||||||
goto cmd_fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
evbase_mpd = event_base_new();
|
evbase_mpd = event_base_new();
|
||||||
if (!evbase_mpd)
|
if (!evbase_mpd)
|
||||||
{
|
{
|
||||||
|
@ -4799,15 +4697,7 @@ int mpd_init(void)
|
||||||
|
|
||||||
event_add(g_exitev, NULL);
|
event_add(g_exitev, NULL);
|
||||||
|
|
||||||
|
cmdbase = commands_base_new(evbase_mpd);
|
||||||
g_cmdev = event_new(evbase_mpd, g_cmd_pipe[0], EV_READ, command_cb, NULL);
|
|
||||||
if (!g_cmdev)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_MPD, "Could not create cmd event\n");
|
|
||||||
goto evnew_fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
event_add(g_cmdev, NULL);
|
|
||||||
|
|
||||||
if (v6enabled)
|
if (v6enabled)
|
||||||
{
|
{
|
||||||
|
@ -4917,15 +4807,12 @@ int mpd_init(void)
|
||||||
evhttp_fail:
|
evhttp_fail:
|
||||||
evconnlistener_free(listener);
|
evconnlistener_free(listener);
|
||||||
connew_fail:
|
connew_fail:
|
||||||
|
commands_base_free(cmdbase);
|
||||||
evnew_fail:
|
evnew_fail:
|
||||||
event_base_free(evbase_mpd);
|
event_base_free(evbase_mpd);
|
||||||
evbase_mpd = NULL;
|
evbase_mpd = NULL;
|
||||||
|
|
||||||
evbase_fail:
|
evbase_fail:
|
||||||
close(g_cmd_pipe[0]);
|
|
||||||
close(g_cmd_pipe[1]);
|
|
||||||
|
|
||||||
cmd_fail:
|
|
||||||
close(g_exit_pipe[0]);
|
close(g_exit_pipe[0]);
|
||||||
close(g_exit_pipe[1]);
|
close(g_exit_pipe[1]);
|
||||||
|
|
||||||
|
@ -4966,6 +4853,8 @@ void mpd_deinit(void)
|
||||||
free(temp);
|
free(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
commands_base_free(cmdbase);
|
||||||
|
|
||||||
http_port = cfg_getint(cfg_getsec(cfg, "mpd"), "http_port");
|
http_port = cfg_getint(cfg_getsec(cfg, "mpd"), "http_port");
|
||||||
if (http_port > 0)
|
if (http_port > 0)
|
||||||
evhttp_free(evhttpd);
|
evhttp_free(evhttpd);
|
||||||
|
@ -4978,6 +4867,4 @@ void mpd_deinit(void)
|
||||||
// Close pipes
|
// Close pipes
|
||||||
close(g_exit_pipe[0]);
|
close(g_exit_pipe[0]);
|
||||||
close(g_exit_pipe[1]);
|
close(g_exit_pipe[1]);
|
||||||
close(g_cmd_pipe[0]);
|
|
||||||
close(g_cmd_pipe[1]);
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue