X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=afs.c;h=a16252cdf037e50bdd415b8978968b638b508f0c;hp=fa4f4326cc110cd377ab6e8a7c30c74fe8148373;hb=19d0ffee2c551fb8d17f01f5bd04b0c52987147b;hpb=f76ab46a9216133332cb7e17d38d392caeca22cb diff --git a/afs.c b/afs.c index fa4f4326..a16252cd 100644 --- a/afs.c +++ b/afs.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2014 Andre Noll + * Copyright (C) 2007 Andre Noll * * Licensed under the GPL v2. For licencing details see COPYING. */ @@ -28,8 +28,8 @@ #include "ipc.h" #include "list.h" #include "sched.h" -#include "signal.h" #include "fd.h" +#include "signal.h" #include "mood.h" #include "sideband.h" #include "command.h" @@ -81,7 +81,7 @@ struct command_task { */ uint32_t cookie; /** The associated task structure. */ - struct task task; + struct task *task; }; extern int mmd_mutex; @@ -89,7 +89,7 @@ extern struct misc_meta_data *mmd; static int server_socket; static struct command_task command_task_struct; -static struct signal_task signal_task_struct; +static struct signal_task *signal_task; static enum play_mode current_play_mode; static char *current_mop; /* mode or playlist specifier. NULL means dummy mood */ @@ -292,10 +292,10 @@ out: * \param result_handler See \ref send_callback_request. * \param private_result_data See \ref send_callback_request. * - * Some commands have a couple of options that are parsed in child context for - * syntactic correctness and are stored in a special options structure for that - * command. This function allows to pass such a structure together with a list - * of further arguments (often a list of audio files) to the parent process. + * Some command handlers pass command-specific options to a callback, together + * with a list of further arguments (often a list of audio files). This + * function allows to pass an arbitrary structure (given as an osl object) and + * a usual argument vector to the specified callback. * * \return The return value of the underlying call to \ref * send_callback_request(). @@ -455,7 +455,7 @@ static int pass_afd(int fd, char *buf, size_t size) } /** - * Open the audio file with highest score. + * Pass the fd of the next audio file to the server process. * * This stores all information for streaming the "best" audio file in a shared * memory area. The id of that area and an open file descriptor for the next @@ -467,27 +467,15 @@ static int pass_afd(int fd, char *buf, size_t size) */ static int open_next_audio_file(void) { - struct osl_row *aft_row; struct audio_file_data afd; int ret, shmid; char buf[8]; - long score; -again: - PARA_NOTICE_LOG("getting next audio file\n"); - ret = score_get_best(&aft_row, &score); + + ret = open_and_update_audio_file(&afd); if (ret < 0) { PARA_ERROR_LOG("%s\n", para_strerror(-ret)); goto no_admissible_files; } - ret = open_and_update_audio_file(aft_row, score, &afd); - if (ret < 0) { - ret = score_delete(aft_row); - if (ret < 0) { - PARA_ERROR_LOG("%s\n", para_strerror(-ret)); - goto no_admissible_files; - } - goto again; - } shmid = ret; if (!write_ok(server_socket)) { ret = -E_AFS_SOCKET; @@ -637,25 +625,19 @@ static int setup_command_socket_or_die(void) { int ret, socket_fd; char *socket_name = conf.afs_socket_arg; - struct sockaddr_un unix_addr; unlink(socket_name); - ret = create_local_socket(socket_name, &unix_addr, - S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IWOTH); + ret = create_local_socket(socket_name, 0); if (ret < 0) { - PARA_EMERG_LOG("%s: %s\n", para_strerror(-ret), socket_name); - exit(EXIT_FAILURE); + ret = create_local_socket(socket_name, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IWOTH); + if (ret < 0) { + PARA_EMERG_LOG("%s: %s\n", para_strerror(-ret), + socket_name); + exit(EXIT_FAILURE); + } } socket_fd = ret; - if (listen(socket_fd , 5) < 0) { - PARA_EMERG_LOG("can not listen on socket\n"); - exit(EXIT_FAILURE); - } - ret = mark_fd_nonblocking(socket_fd); - if (ret < 0) { - close(socket_fd); - return ret; - } PARA_INFO_LOG("listening on socket %s (fd %d)\n", socket_name, socket_fd); return socket_fd; @@ -719,13 +701,7 @@ static int open_afs_tables(void) return ret; } -static void signal_pre_select(struct sched *s, struct task *t) -{ - struct signal_task *st = container_of(t, struct signal_task, task); - para_fd_set(st->fd, &s->rfds, &s->max_fileno); -} - -static int afs_signal_post_select(struct sched *s, __a_unused struct task *t) +static int afs_signal_post_select(struct sched *s, __a_unused void *context) { int signum, ret; @@ -753,24 +729,24 @@ shutdown: static void register_signal_task(struct sched *s) { - struct signal_task *st = &signal_task_struct; - para_sigaction(SIGPIPE, SIG_IGN); - st->fd = para_signal_init(); - PARA_INFO_LOG("signal pipe: fd %d\n", st->fd); + signal_task = signal_init_or_die(); para_install_sighandler(SIGINT); para_install_sighandler(SIGTERM); para_install_sighandler(SIGHUP); - st->task.pre_select = signal_pre_select; - st->task.post_select = afs_signal_post_select; - sprintf(st->task.status, "signal task"); - register_task(s, &st->task); + signal_task->task = task_register(&(struct task_info) { + .name = "signal", + .pre_select = signal_pre_select, + .post_select = afs_signal_post_select, + .context = signal_task, + + }, s); } static struct list_head afs_client_list; -/** Describes on connected afs client. */ +/** Describes one connected afs client. */ struct afs_client { /** Position in the afs client list. */ struct list_head node; @@ -780,9 +756,9 @@ struct afs_client { struct timeval connect_time; }; -static void command_pre_select(struct sched *s, struct task *t) +static void command_pre_select(struct sched *s, void *context) { - struct command_task *ct = container_of(t, struct command_task, task); + struct command_task *ct = context; struct afs_client *client; para_fd_set(server_socket, &s->rfds, &s->max_fileno); @@ -917,14 +893,14 @@ err: /** Shutdown connection if query has not arrived until this many seconds. */ #define AFS_CLIENT_TIMEOUT 3 -static int command_post_select(struct sched *s, struct task *t) +static int command_post_select(struct sched *s, void *context) { - struct command_task *ct = container_of(t, struct command_task, task); + struct command_task *ct = context; struct sockaddr_un unix_addr; struct afs_client *client, *tmp; int fd, ret; - ret = task_get_notification(t); + ret = task_get_notification(ct->task); if (ret < 0) return ret; ret = execute_server_command(&s->rfds); @@ -972,10 +948,12 @@ static void register_command_task(uint32_t cookie, struct sched *s) ct->fd = setup_command_socket_or_die(); ct->cookie = cookie; - ct->task.pre_select = command_pre_select; - ct->task.post_select = command_post_select; - sprintf(ct->task.status, "afs command task"); - register_task(s, &ct->task); + ct->task = task_register(&(struct task_info) { + .name = "afs command", + .pre_select = command_pre_select, + .post_select = command_post_select, + .context = ct, + }, s); } /** @@ -1007,6 +985,7 @@ __noreturn void afs_init(uint32_t cookie, int socket_fd) s.default_timeout.tv_sec = 0; s.default_timeout.tv_usec = 999 * 1000; ret = schedule(&s); + sched_shutdown(&s); out_close: close_afs_tables(); out: