X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=vss.c;h=f6da52dd6cc933f66a746095389ad1510452d0e4;hp=ba6f7c4c655134d11d79e6411ab92d63b4efd160;hb=89f2de1016601e523fd456e0e2fa650fa695ecaa;hpb=92e4a0579a320372d2e94efc7c2a0d9f419e3ffe diff --git a/vss.c b/vss.c index ba6f7c4c..f6da52dd 100644 --- a/vss.c +++ b/vss.c @@ -12,7 +12,6 @@ */ #include -#include #include #include "para.h" @@ -133,6 +132,7 @@ struct fec_group { uint16_t slice_bytes; }; +/** A FEC client is always in one of these states. */ enum fec_client_state { FEC_STATE_NONE = 0, /**< not initialized and not enabled */ FEC_STATE_DISABLED, /**< temporarily disabled */ @@ -542,6 +542,7 @@ static int setup_next_fec_group(struct fec_client *fc, struct vss_task *vsst) /* setup header slices */ buf = vsst->header_buf; for (i = 0; i < g->num_header_slices; i++) { + uint32_t payload_size; if (buf + g->slice_bytes <= vsst->header_buf + vsst->header_len) { fc->src_data[i] = (const unsigned char *)buf; buf += g->slice_bytes; @@ -552,8 +553,7 @@ static int setup_next_fec_group(struct fec_client *fc, struct vss_task *vsst) * goes beyond the buffer. This slice will not be fully * used. */ - uint32_t payload_size = vsst->header_buf - + vsst->header_len - buf; + payload_size = vsst->header_buf + vsst->header_len - buf; memcpy(fc->extra_header_buf, buf, payload_size); if (payload_size < g->slice_bytes) memset(fc->extra_header_buf + payload_size, 0, @@ -689,26 +689,6 @@ static int next_slice_is_due(struct fec_client *fc, struct timeval *diff) return ret < 0? 1 : 0; } -static void compute_slice_timeout(struct timeval *timeout) -{ - struct fec_client *fc; - - list_for_each_entry(fc, &fec_client_list, node) { - struct timeval diff; - - if (fc->state != FEC_STATE_READY_TO_RUN) - continue; - if (next_slice_is_due(fc, &diff)) { - timeout->tv_sec = 0; - timeout->tv_usec = 0; - return; - } - /* timeout = min(timeout, diff) */ - if (tv_diff(&diff, timeout, NULL) < 0) - *timeout = diff; - } -} - static void set_eof_barrier(struct vss_task *vsst) { struct fec_client *fc; @@ -799,42 +779,38 @@ static int chk_barrier(const char *bname, const struct timeval *barrier, return -1; } -/* - * != NULL: timeout for next chunk - * NULL: nothing to do - */ -static struct timeval *vss_compute_timeout(struct vss_task *vsst) +static void vss_compute_timeout(struct sched *s, struct vss_task *vsst) { - static struct timeval the_timeout; - struct timeval next_chunk; - - if (vss_next() && vsst->map) { - /* only sleep a bit, nec*/ - the_timeout.tv_sec = 0; - the_timeout.tv_usec = 100; - return &the_timeout; - } - if (chk_barrier("autoplay_delay", &vsst->autoplay_barrier, - &the_timeout, 1) < 0) - return &the_timeout; - if (chk_barrier("eof", &vsst->eof_barrier, &the_timeout, 1) < 0) - return &the_timeout; - if (chk_barrier("data send", &vsst->data_send_barrier, - &the_timeout, 1) < 0) - return &the_timeout; + struct timeval tv; + struct fec_client *fc; + if (!vss_playing() || !vsst->map) - return NULL; + return; + if (vss_next() && vsst->map) /* only sleep a bit, nec*/ + return sched_request_timeout_ms(100, s); + + /* Each of these barriers must have passed until we may proceed */ + if (sched_request_barrier(&vsst->autoplay_barrier, s) == 1) + return; + if (sched_request_barrier(&vsst->eof_barrier, s) == 1) + return; + if (sched_request_barrier(&vsst->data_send_barrier, s) == 1) + return; + /* + * Compute the select timeout as the minimal time until the next + * chunk/slice is due for any client. + */ compute_chunk_time(mmd->chunks_sent, &mmd->afd.afhi.chunk_tv, - &mmd->stream_start, &next_chunk); - if (chk_barrier("chunk", &next_chunk, &the_timeout, 0) >= 0) { - /* chunk is due or bof */ - the_timeout.tv_sec = 0; - the_timeout.tv_usec = 0; - return &the_timeout; + &mmd->stream_start, &tv); + if (sched_request_barrier_or_min_delay(&tv, s) == 0) + return; + list_for_each_entry(fc, &fec_client_list, node) { + if (fc->state != FEC_STATE_READY_TO_RUN) + continue; + if (next_slice_is_due(fc, &tv)) + return sched_min_delay(s); + sched_request_timeout(&tv, s); } - /* compute min of current timeout and next slice time */ - compute_slice_timeout(&the_timeout); - return &the_timeout; } static void vss_eof(struct vss_task *vsst) @@ -903,7 +879,6 @@ static void set_mmd_offset(void) static void vss_pre_select(struct sched *s, struct task *t) { int i; - struct timeval *tv; struct vss_task *vsst = container_of(t, struct vss_task, task); if (!vsst->map || vss_next() || vss_paused() || vss_repos()) { @@ -941,9 +916,7 @@ static void vss_pre_select(struct sched *s, struct task *t) continue; senders[i].pre_select(&s->max_fileno, &s->rfds, &s->wfds); } - tv = vss_compute_timeout(vsst); - if (tv) - sched_request_timeout(tv, s); + vss_compute_timeout(s, vsst); } static int recv_afs_msg(int afs_socket, int *fd, uint32_t *code, uint32_t *data)