X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=vss.c;h=2acff1cb95b8e0b54a37eeb96aa653fd16443e4c;hp=2349b0931cfcc22b4d54b01f6c26f6b545614e6a;hb=33434de86d9f9c237b7bfb1204512404c42e83ff;hpb=f6a99f9e27cf84d92fc992677dca9578c5a3b585 diff --git a/vss.c b/vss.c index 2349b093..2acff1cb 100644 --- a/vss.c +++ b/vss.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1997-2013 Andre Noll + * Copyright (C) 1997 Andre Noll * * Licensed under the GPL v2. For licencing details see COPYING. */ @@ -89,7 +89,7 @@ struct vss_task { /** The memory mapped audio file. */ char *map; /** Used by the scheduler. */ - struct task task; + struct task *task; /** Pointer to the header of the mapped audio file. */ char *header_buf; /** Length of the audio file header. */ @@ -855,7 +855,6 @@ static void vss_eof(struct vss_task *vsst) mmd->afd.afhi.chunk_tv.tv_usec = 0; free(mmd->afd.afhi.chunk_table); mmd->afd.afhi.chunk_table = NULL; - mmd->mtime = 0; mmd->size = 0; mmd->events++; } @@ -885,49 +884,11 @@ static void set_mmd_offset(void) mmd->offset = tv2ms(&offset); } -/** - * Compute the timeout for the main select-loop of the scheduler. - * - * \param s Pointer to the server scheduler. - * \param t Pointer to the vss task structure. - * - * Before the timeout is computed, the current vss status flags are evaluated - * and acted upon by calling appropriate functions from the lower layers. - * Possible actions include - * - * - request a new audio file from afs, - * - shutdown of all senders (stop/pause command), - * - reposition the stream (ff/jmp command). - */ -static void vss_pre_select(struct sched *s, struct task *t) +static void vss_pre_select(struct sched *s, void *context) { int i; - struct vss_task *vsst = container_of(t, struct vss_task, task); + struct vss_task *vsst = context; - if (!vsst->map || vss_next() || vss_paused() || vss_repos()) { - struct fec_client *fc, *tmp; - for (i = 0; senders[i].name; i++) - if (senders[i].shutdown_clients) - senders[i].shutdown_clients(); - list_for_each_entry_safe(fc, tmp, &fec_client_list, node) - fc->state = FEC_STATE_NONE; - mmd->stream_start.tv_sec = 0; - mmd->stream_start.tv_usec = 0; - } - if (vss_next()) - vss_eof(vsst); - else if (vss_paused()) { - if (mmd->chunks_sent) - set_eof_barrier(vsst); - mmd->chunks_sent = 0; - } else if (vss_repos()) { - tv_add(now, &vsst->announce_tv, &vsst->data_send_barrier); - set_eof_barrier(vsst); - mmd->chunks_sent = 0; - mmd->current_chunk = mmd->repos_request; - mmd->new_vss_status_flags &= ~VSS_REPOS; - set_mmd_offset(); - } if (need_to_request_new_audio_file(vsst)) { PARA_DEBUG_LOG("ready and playing, but no audio file\n"); para_fd_set(vsst->afs_socket, &s->wfds, &s->max_fileno); @@ -944,7 +905,7 @@ static void vss_pre_select(struct sched *s, struct task *t) static int recv_afs_msg(int afs_socket, int *fd, uint32_t *code, uint32_t *data) { - char control[255], buf[8]; + char control[255] __a_aligned(8), buf[8]; struct msghdr msg = {.msg_iov = NULL}; struct cmsghdr *cmsg; struct iovec iov; @@ -1013,7 +974,6 @@ static void recv_afs_result(struct vss_task *vsst, fd_set *rfds) goto err; } mmd->size = statbuf.st_size; - mmd->mtime = statbuf.st_mtime; ret = para_mmap(mmd->size, PROT_READ, MAP_PRIVATE | MAP_POPULATE, passed_fd, 0, &vsst->map); if (ret < 0) @@ -1126,11 +1086,38 @@ static void vss_send(struct vss_task *vsst) } } -static int vss_post_select(struct sched *s, struct task *t) +static int vss_post_select(struct sched *s, void *context) { int ret, i; - struct vss_task *vsst = container_of(t, struct vss_task, task); + struct vss_task *vsst = context; + if (!vsst->map || vss_next() || vss_paused() || vss_repos()) { + /* shut down senders and fec clients */ + struct fec_client *fc, *tmp; + for (i = 0; senders[i].name; i++) + if (senders[i].shutdown_clients) + senders[i].shutdown_clients(); + list_for_each_entry_safe(fc, tmp, &fec_client_list, node) + fc->state = FEC_STATE_NONE; + mmd->stream_start.tv_sec = 0; + mmd->stream_start.tv_usec = 0; + } + if (vss_next()) + vss_eof(vsst); + else if (vss_paused()) { + if (mmd->chunks_sent) + set_eof_barrier(vsst); + mmd->chunks_sent = 0; + } else if (vss_repos()) { /* repositioning due to ff/jmp command */ + tv_add(now, &vsst->announce_tv, &vsst->data_send_barrier); + set_eof_barrier(vsst); + mmd->chunks_sent = 0; + mmd->current_chunk = afh_get_start_chunk(mmd->repos_request, + &mmd->afd.afhi); + mmd->new_vss_status_flags &= ~VSS_REPOS; + set_mmd_offset(); + } + /* If a sender command is pending, run it. */ if (mmd->sender_cmd_data.cmd_num >= 0) { int num = mmd->sender_cmd_data.cmd_num, sender_num = mmd->sender_cmd_data.sender_num; @@ -1185,8 +1172,6 @@ void init_vss_task(int afs_socket, struct sched *s) conf.autoplay_delay_arg : 0; vsst->header_interval.tv_sec = 5; /* should this be configurable? */ 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)); INIT_LIST_HEAD(&fec_client_list); @@ -1202,10 +1187,14 @@ void init_vss_task(int afs_socket, struct sched *s) 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(clock_get_realtime(NULL), &tmp, &vsst->autoplay_barrier); tv_add(&vsst->autoplay_barrier, &vsst->announce_tv, &vsst->data_send_barrier); } - sprintf(vsst->task.status, "vss task"); - register_task(s, &vsst->task); + vsst->task = task_register(&(struct task_info) { + .name = "vss task", + .pre_select = vss_pre_select, + .post_select = vss_post_select, + .context = vsst, + }, s); }