server: Constify return value of lookup_user().
[paraslash.git] / prebuffer_filter.c
1 /* Copyright (C) 2009 Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */
2
3 /** \file prebuffer_filter.c Paraslash's prebuffering filter. */
4
5 #include <regex.h>
6 #include <lopsub.h>
7
8 #include "para.h"
9 #include "filter_cmd.lsg.h"
10 #include "list.h"
11 #include "sched.h"
12 #include "buffer_tree.h"
13 #include "filter.h"
14 #include "string.h"
15 #include "error.h"
16
17 /** Data specific to the prebuffer filter. */
18 struct private_prebuffer_data {
19         /** Number of bytes prebuffered or -1 if no longer prebuffering. */
20         int prebuffered;
21         /** End of prebuffering period. */
22         struct timeval barrier;
23 };
24
25 static void prebuffer_pre_select(struct sched *s, void *context)
26 {
27         struct filter_node *fn = context;
28         struct btr_node *btrn = fn->btrn;
29         size_t iqs = btr_get_input_queue_size(btrn);
30         struct private_prebuffer_data *ppd = fn->private_data;
31         struct timeval diff;
32
33         if (iqs == 0)
34                 return;
35         if (ppd->barrier.tv_sec == 0) {
36                 uint32_t duration = FILTER_CMD_OPT_UINT32_VAL(PREBUFFER,
37                         DURATION, fn->lpr);
38                 struct timeval tv;
39                 PARA_INFO_LOG("prebuffer period %" PRIu32 "ms\n", duration);
40                 ms2tv(duration, &tv);
41                 tv_add(&tv, now, &ppd->barrier);
42         }
43         if (tv_diff(&ppd->barrier, now, &diff) < 0)
44                 return sched_min_delay(s);
45         sched_request_timeout(&diff, s);
46 }
47
48 static void prebuffer_close(struct filter_node *fn)
49 {
50         free(fn->private_data);
51 }
52
53 static int prebuffer_post_select(__a_unused struct sched *s, void *context)
54 {
55         struct filter_node *fn = context;
56         struct btr_node *btrn = fn->btrn;
57         size_t iqs = btr_get_input_queue_size(btrn);
58         struct private_prebuffer_data *ppd = fn->private_data;
59         uint32_t size = FILTER_CMD_OPT_UINT32_VAL(PREBUFFER, SIZE, fn->lpr);
60
61         if (ppd->barrier.tv_sec == 0)
62                 return 0;
63         if (tv_diff(now, &ppd->barrier, NULL) < 0)
64                 return 0;
65         if (iqs < size)
66                 return 0;
67         btr_splice_out_node(&fn->btrn);
68         return -E_PREBUFFER_SUCCESS;
69 }
70
71 static void prebuffer_open(struct filter_node *fn)
72 {
73         struct private_prebuffer_data *ppd = para_calloc(sizeof(*ppd));
74         fn->private_data = ppd;
75 }
76
77 const struct filter lsg_filter_cmd_com_prebuffer_user_data = {
78         .open = prebuffer_open,
79         .close = prebuffer_close,
80         .pre_select = prebuffer_pre_select,
81         .post_select = prebuffer_post_select,
82 };