Modify player-to-DACP status update communication

Have DACP set a callback (through a sync_command() setter) into the player
instead of setting an fd without any locking. All the code now lies in DACP
instead of being split between DACP and the player.
This commit is contained in:
Julien BLACHE 2010-09-12 14:31:41 +02:00
parent 90b13b1855
commit 942f3e4aad
3 changed files with 52 additions and 35 deletions

View File

@ -342,6 +342,25 @@ playstatusupdate_cb(int fd, short what, void *arg)
DPRINTF(E_LOG, L_DACP, "Couldn't re-add event for playstatusupdate\n"); DPRINTF(E_LOG, L_DACP, "Couldn't re-add event for playstatusupdate\n");
} }
/* Thread: player */
static void
dacp_playstatus_update_handler(void)
{
int ret;
#ifdef USE_EVENTFD
ret = eventfd_write(update_efd, 1);
if (ret < 0)
DPRINTF(E_LOG, L_DACP, "Could not send status update event: %s\n", strerror(errno));
#else
int dummy = 42;
ret = write(update_pipe[1], &dummy, sizeof(dummy));
if (ret != sizeof(dummy))
DPRINTF(E_LOG, L_DACP, "Could not write to status update fd: %s\n", strerror(errno));
#endif
}
static void static void
update_fail_cb(struct evhttp_connection *evcon, void *arg) update_fail_cb(struct evhttp_connection *evcon, void *arg)
{ {
@ -1794,11 +1813,7 @@ dacp_init(void)
event_base_set(evbase_httpd, &updateev); event_base_set(evbase_httpd, &updateev);
event_add(&updateev, NULL); event_add(&updateev, NULL);
#ifdef USE_EVENTFD player_set_update_handler(dacp_playstatus_update_handler);
player_set_updatefd(update_efd);
#else
player_set_updatefd(update_pipe[1]);
#endif
return 0; return 0;
@ -1823,6 +1838,8 @@ dacp_deinit(void)
struct dacp_update_request *ur; struct dacp_update_request *ur;
int i; int i;
player_set_update_handler(NULL);
for (i = 0; dacp_handlers[i].handler; i++) for (i = 0; dacp_handlers[i].handler; i++)
regfree(&dacp_handlers[i].preg); regfree(&dacp_handlers[i].preg);
@ -1839,8 +1856,6 @@ dacp_deinit(void)
free(ur); free(ur);
} }
player_set_updatefd(-1);
event_del(&updateev); event_del(&updateev);
avl_free_tree(dacp_props_hash); avl_free_tree(dacp_props_hash);

View File

@ -129,7 +129,7 @@ static enum repeat_mode repeat;
static char shuffle; static char shuffle;
/* Status updates (for DACP) */ /* Status updates (for DACP) */
static int update_fd; static player_status_handler update_handler;
/* Playback timer */ /* Playback timer */
static int pb_timer_fd; static int pb_timer_fd;
@ -181,26 +181,10 @@ static struct evbuffer *audio_buf;
static void static void
status_update(enum play_status status) status_update(enum play_status status)
{ {
#ifndef USE_EVENTFD
int dummy = 42;
#endif
int ret;
player_state = status; player_state = status;
if (update_fd < 0) if (update_handler)
return; update_handler();
#ifdef USE_EVENTFD
ret = eventfd_write(update_fd, 1);
if (ret < 0)
#else
ret = write(update_fd, &dummy, sizeof(dummy));
if (ret != sizeof(dummy))
#endif
{
DPRINTF(E_LOG, L_PLAYER, "Could not send status update: %s\n", strerror(errno));
}
} }
@ -2467,6 +2451,17 @@ queue_plid(void *arg)
return 0; return 0;
} }
static int
set_update_handler(void *arg)
{
player_status_handler handler;
handler = (player_status_handler)arg;
update_handler = handler;
return 0;
}
/* Command helpers */ /* Command helpers */
/* Thread: player */ /* Thread: player */
@ -2842,6 +2837,19 @@ player_queue_plid(uint32_t plid)
pthread_mutex_unlock(&cmd_lck); pthread_mutex_unlock(&cmd_lck);
} }
void
player_set_update_handler(player_status_handler handler)
{
pthread_mutex_lock(&cmd_lck);
cmd.func = set_update_handler;
cmd.func_bh = NULL;
cmd.arg = handler;
sync_command();
pthread_mutex_unlock(&cmd_lck);
}
/* Thread: main (mdns) */ /* Thread: main (mdns) */
static void static void
@ -3176,13 +3184,6 @@ exit_cb(int fd, short what, void *arg)
player_exit = 1; player_exit = 1;
} }
/* Thread: main at DACP init/deinit */
void
player_set_updatefd(int fd)
{
update_fd = fd;
}
/* Thread: main */ /* Thread: main */
int int
player_init(void) player_init(void)
@ -3212,7 +3213,7 @@ player_init(void)
repeat = REPEAT_OFF; repeat = REPEAT_OFF;
shuffle = 0; shuffle = 0;
update_fd = -1; update_handler = NULL;
/* Random RTP time start */ /* Random RTP time start */
gcry_randomize(&rnd, sizeof(rnd), GCRY_STRONG_RANDOM); gcry_randomize(&rnd, sizeof(rnd), GCRY_STRONG_RANDOM);

View File

@ -46,6 +46,7 @@ struct player_status {
}; };
typedef void (*spk_enum_cb)(uint64_t id, const char *name, int selected, int has_password, void *arg); typedef void (*spk_enum_cb)(uint64_t id, const char *name, int selected, int has_password, void *arg);
typedef void (*player_status_handler)(void);
struct player_source; struct player_source;
@ -112,7 +113,7 @@ player_queue_plid(uint32_t plid);
void void
player_set_updatefd(int fd); player_set_update_handler(player_status_handler handler);
int int
player_init(void); player_init(void);