Merge branch 't/writer_setup_cleanup'
[paraslash.git] / vss.c
diff --git a/vss.c b/vss.c
index dfd80ebcb817526c6e0c5c4f62eeb07ae6fc9375..b9afc8ed637374c82918f3448695a1a2fdaa94a2 100644 (file)
--- a/vss.c
+++ b/vss.c
@@ -541,6 +541,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;
@@ -551,8 +552,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,
@@ -688,26 +688,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;
@@ -798,42 +778,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)
@@ -902,7 +878,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()) {
@@ -940,9 +915,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)