afs: Use nonblocking API for server commands.
[paraslash.git] / afs.c
diff --git a/afs.c b/afs.c
index 1350db3423c3a184cb645e09cae9a2ebb060358b..40ef7ad25e454f312a55a48699ca896b59da7171 100644 (file)
--- a/afs.c
+++ b/afs.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007-2009 Andre Noll <maan@systemlinux.org>
+ * Copyright (C) 2007-2010 Andre Noll <maan@systemlinux.org>
  *
  * Licensed under the GPL v2. For licencing details see COPYING.
  */
@@ -709,15 +709,16 @@ static void signal_pre_select(struct sched *s, struct task *t)
 
 static void afs_signal_post_select(struct sched *s, struct task *t)
 {
-       struct signal_task *st = container_of(t, struct signal_task, task);
+       int signum;
+
        if (getppid() == 1) {
                PARA_EMERG_LOG("para_server died\n");
                goto shutdown;
        }
-       if (!FD_ISSET(st->fd, &s->rfds))
+       signum = para_next_signal(&s->rfds);
+       if (signum == 0)
                return;
-       st->signum = para_next_signal();
-       if (st->signum == SIGHUP) {
+       if (signum == SIGHUP) {
                close_afs_tables();
                parse_config_or_die(1);
                t->error = open_afs_tables();
@@ -726,7 +727,7 @@ static void afs_signal_post_select(struct sched *s, struct task *t)
                init_admissible_files(current_mop);
                return;
        }
-       PARA_EMERG_LOG("terminating on signal %d\n", st->signum);
+       PARA_EMERG_LOG("terminating on signal %d\n", signum);
 shutdown:
        sched_shutdown();
        t->error = -E_AFS_SIGNAL;
@@ -842,24 +843,18 @@ static int call_callback(int fd, int query_shmid)
        return shm_detach(query_shm);
 }
 
-static int execute_server_command(void)
+static int execute_server_command(fd_set *rfds)
 {
        char buf[8];
-       int ret = recv_bin_buffer(server_socket, buf, sizeof(buf) - 1);
+       size_t n;
+       int ret = read_nonblock(server_socket, buf, sizeof(buf) - 1, rfds, &n);
 
-       if (ret <= 0) {
-               if (!ret)
-                       ret = -ERRNO_TO_PARA_ERROR(ECONNRESET);
-               goto err;
-       }
-       buf[ret] = '\0';
-       PARA_DEBUG_LOG("received: %s\n", buf);
-       ret = -E_BAD_CMD;
+       if (ret < 0 || n == 0)
+               return ret;
+       buf[n] = '\0';
        if (strcmp(buf, "new"))
-               goto err;
-       ret = open_next_audio_file();
-err:
-       return ret;
+               return -E_BAD_CMD;
+       return open_next_audio_file();
 }
 
 static void execute_afs_command(int fd, uint32_t expected_cookie)
@@ -905,15 +900,12 @@ static void command_post_select(struct sched *s, struct task *t)
        struct afs_client *client, *tmp;
        int fd, ret;
 
-       if (FD_ISSET(server_socket, &s->rfds)) {
-               ret = execute_server_command();
-               if (ret < 0) {
-                       PARA_EMERG_LOG("%s\n", para_strerror(-ret));
-                       sched_shutdown();
-                       return;
-               }
+       ret = execute_server_command(&s->rfds);
+       if (ret < 0) {
+               PARA_EMERG_LOG("%s\n", para_strerror(-ret));
+               sched_shutdown();
+               return;
        }
-
        /* Check the list of connected clients. */
        list_for_each_entry_safe(client, tmp, &afs_client_list, node) {
                if (FD_ISSET(client->fd, &s->rfds))
@@ -930,14 +922,11 @@ static void command_post_select(struct sched *s, struct task *t)
                free(client);
        }
        /* Accept connections on the local socket. */
-       if (!FD_ISSET(ct->fd, &s->rfds))
-               return;
-       ret = para_accept(ct->fd, &unix_addr, sizeof(unix_addr));
-       if (ret < 0) {
+       ret = para_accept(ct->fd, &s->rfds, &unix_addr, sizeof(unix_addr), &fd);
+       if (ret < 0)
                PARA_NOTICE_LOG("%s\n", para_strerror(-ret));
+       if (ret <= 0)
                return;
-       }
-       fd = ret;
        ret = mark_fd_nonblocking(fd);
        if (ret < 0) {
                PARA_NOTICE_LOG("%s\n", para_strerror(-ret));
@@ -1151,12 +1140,30 @@ void afs_event(enum afs_events event, struct para_buffer *pb,
        }
 }
 
+/**
+ * Dummy event handler for the images table.
+ *
+ * \param event Unused.
+ * \param pb Unused.
+ * \param data Unused.
+ *
+ * This table does not honor events.
+ */
 int images_event_handler(__a_unused enum afs_events event,
        __a_unused  struct para_buffer *pb, __a_unused void *data)
 {
        return 1;
 }
 
+/**
+ * Dummy event handler for the lyrics table.
+ *
+ * \param event Unused.
+ * \param pb Unused.
+ * \param data Unused.
+ *
+ * This table does not honor events.
+ */
 int lyrics_event_handler(__a_unused enum afs_events event,
        __a_unused struct para_buffer *pb, __a_unused void *data)
 {