-/**
- * compute the timeout for para_server's main select-loop
- *
- * This function gets called from para_server to determine the timeout value
- * for its main select loop.
- *
- * Before the timeout is computed, the current afs status flags are evaluated
- * and acted upon by calling appropriate functions from the lower layers.
- * Possible actions include
- *
- * - request a new file list from the current dabase tool (audio file change)
- * - shutdown of all senders (stop/pause command)
- * - repositioning of the stream (ff/jmp command)
- *
- * \return A pointer to a struct timeval containing the timeout for the next
- * chunk of data to be sent, or NULL if we're not sending right now.
- */
-struct timeval *afs_preselect(void)
-{
- struct audio_format *af = NULL;
- int i, format;
- struct timeval *ret;
-again:
- format = mmd->audio_format;
- if (format >= 0)
- af = afl + format;
- else
- for (i = 0; senders[i].name; i++)
- senders[i].shutdown_clients();
- if (afs_next() && af) {
- afs_eof(af);
- return afs_compute_timeout();
+static void register_command_task(uint32_t cookie)
+{
+ static struct command_task command_task_struct;
+ struct command_task *ct = &command_task_struct;
+ ct->fd = setup_command_socket_or_die();
+ ct->cookie = cookie;
+
+ ct->task.pre_select = command_pre_select;
+ ct->task.post_select = command_post_select;
+ ct->task.private_data = ct;
+ sprintf(ct->task.status, "command task");
+ register_task(&ct->task);
+}
+
+void register_tasks(uint32_t cookie)
+{
+ register_signal_task();
+ register_command_task(cookie);
+}
+
+__noreturn int afs_init(uint32_t cookie, int socket_fd)
+{
+ int ret;
+// void *shm_area;
+ enum play_mode current_play_mode;
+ struct sched s;
+
+ server_socket = socket_fd;
+ PARA_INFO_LOG("server_socket: %d, afs_socket_cookie: %u\n",
+ server_socket, (unsigned) cookie);
+
+ ret = attribute_init(&afs_tables[TBLNUM_ATTRIBUTES]);
+ if (ret < 0)
+ goto attribute_init_error;
+ ret = moods_init(&afs_tables[TBLNUM_MOODS]);
+ if (ret < 0)
+ goto moods_init_error;
+ ret = playlists_init(&afs_tables[TBLNUM_PLAYLIST]);
+ if (ret < 0)
+ goto playlists_init_error;
+ ret = lyrics_init(&afs_tables[TBLNUM_LYRICS]);
+ if (ret < 0)
+ goto lyrics_init_error;
+ ret = images_init(&afs_tables[TBLNUM_IMAGES]);
+ if (ret < 0)
+ goto images_init_error;
+ ret = score_init(&afs_tables[TBLNUM_SCORES]);
+ if (ret < 0)
+ goto score_init_error;
+ ret = aft_init(&afs_tables[TBLNUM_AUDIO_FILES]);
+ if (ret < 0)
+ goto aft_init_error;
+
+ current_play_mode = init_admissible_files();
+ register_tasks(cookie);
+ s.default_timeout.tv_sec = 0;
+ s.default_timeout.tv_usec = 99 * 1000;
+ sched(&s);
+
+#if 0
+ ret = shm_new(sizeof(struct callback_data));
+ if (ret < 0)
+ return ret;
+ shmid = ret;
+ ret = shm_attach(shmid, ATTACH_RW, &shm_area);
+ if (ret < 0)
+ return ret;
+ shm_callback_data = shm_area;
+ ret = mutex_new();
+ if (ret < 0)
+ return ret;
+ callback_mutex = ret;
+ ret = mutex_new();
+ if (ret < 0)
+ return ret;
+ child_mutex = ret;
+ ret = mutex_new();
+ if (ret < 0)
+ return ret;
+ result_mutex = ret;
+ mutex_lock(result_mutex);
+#endif
+aft_init_error:
+ score_shutdown(OSL_MARK_CLEAN);
+score_init_error:
+ images_shutdown(OSL_MARK_CLEAN);
+images_init_error:
+ lyrics_shutdown(OSL_MARK_CLEAN);
+lyrics_init_error:
+ playlists_shutdown(OSL_MARK_CLEAN);
+playlists_init_error:
+ moods_shutdown(OSL_MARK_CLEAN);
+moods_init_error:
+ attribute_shutdown(OSL_MARK_CLEAN);
+attribute_init_error:
+ exit(EXIT_FAILURE);
+}
+
+static int create_all_tables(void)
+{
+ int i, ret;
+
+ for (i = 0; i < NUM_AFS_TABLES; i++) {
+ struct table_info *ti = afs_tables + i;
+
+ if (ti->flags & TBLFLAG_SKIP_CREATE)
+ continue;
+ ret = osl_create_table(ti->desc);
+ if (ret < 0)
+ return ret;