+
+static void vss_post_select(struct sched *s, struct task *t)
+{
+ int ret, i;
+ struct vss_task *vsst = container_of(t, struct vss_task, task);
+
+ if (mmd->sender_cmd_data.cmd_num >= 0) {
+ int num = mmd->sender_cmd_data.cmd_num,
+ sender_num = mmd->sender_cmd_data.sender_num;
+
+ if (senders[sender_num].client_cmds[num])
+ senders[sender_num].client_cmds[num](&mmd->sender_cmd_data);
+ mmd->sender_cmd_data.cmd_num = -1;
+ }
+ if (vsst->afsss != AFS_SOCKET_CHECK_FOR_WRITE) {
+ if (FD_ISSET(vsst->afs_socket, &s->rfds))
+ recv_afs_result(vsst);
+ } else if (FD_ISSET(vsst->afs_socket, &s->wfds)) {
+ PARA_NOTICE_LOG("requesting new fd from afs\n");
+ ret = send_buffer(vsst->afs_socket, "new");
+ vsst->afsss = AFS_SOCKET_AFD_PENDING;
+ }
+ for (i = 0; senders[i].name; i++) {
+ if (!senders[i].post_select)
+ continue;
+ senders[i].post_select(&s->rfds, &s->wfds);
+ }
+ if ((vss_playing() && !(mmd->vss_status_flags & VSS_PLAYING)) ||
+ (vss_next() && vss_playing()))
+ tv_add(now, &vsst->announce_tv, &vsst->data_send_barrier);
+ vss_send_chunk(vsst);
+}
+
+/**
+ * Initialize the virtual streaming system task.
+ *
+ * \param afs_socket The fd for communication with afs.
+ *
+ * This also initializes all supported senders and starts streaming
+ * if the --autoplay command line flag was given.
+ */
+void init_vss_task(int afs_socket)
+{
+ static struct vss_task vss_task_struct, *vsst = &vss_task_struct;
+ int i;
+ char *hn = para_hostname(), *home = para_homedir();
+ long unsigned announce_time = conf.announce_time_arg > 0?
+ conf.announce_time_arg : 300,
+ autoplay_delay = conf.autoplay_delay_arg > 0?
+ conf.autoplay_delay_arg : 0;
+
+ vsst->afs_socket = afs_socket;
+ vsst->task.pre_select = vss_pre_select;
+ vsst->task.post_select = vss_post_select;
+ ms2tv(announce_time, &vsst->announce_tv);
+ PARA_INFO_LOG("announce timeval: %lums\n", tv2ms(&vsst->announce_tv));
+ for (i = 0; senders[i].name; i++) {
+ PARA_NOTICE_LOG("initializing %s sender\n", senders[i].name);
+ senders[i].init(&senders[i]);
+ }
+ free(hn);
+ free(home);
+ mmd->sender_cmd_data.cmd_num = -1;
+ make_empty_status_items(mmd->afd.verbose_ls_output);
+ if (conf.autoplay_given) {
+ struct timeval tmp;
+ mmd->vss_status_flags |= VSS_PLAYING;
+ mmd->new_vss_status_flags |= VSS_PLAYING;
+ ms2tv(autoplay_delay, &tmp);
+ tv_add(now, &tmp, &vsst->autoplay_barrier);
+ tv_add(&vsst->autoplay_barrier, &vsst->announce_tv,
+ &vsst->data_send_barrier);
+ }
+ register_task(&vsst->task);
+}