1 /*
2  * SpanDSP - a series of DSP components for telephony
3  *
4  * schedule.c
5  *
6  * Written by Steve Underwood <steveu@coppice.org>
7  *
8  * Copyright (C) 2004 Steve Underwood
9  *
10  * All rights reserved.
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU Lesser General Public License version 2.1,
14  * as published by the Free Software Foundation.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with this program; if not, write to the Free Software
23  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  */
25 
26 #if defined(HAVE_CONFIG_H)
27 #include "config.h"
28 #endif
29 
30 #include <stdio.h>
31 #include <inttypes.h>
32 #include <stdlib.h>
33 #include <memory.h>
34 #if defined(HAVE_STDBOOL_H)
35 #include <stdbool.h>
36 #else
37 #include "spandsp/stdbool.h"
38 #endif
39 
40 #include "spandsp/telephony.h"
41 #include "spandsp/alloc.h"
42 #include "spandsp/logging.h"
43 #include "spandsp/schedule.h"
44 
45 #include "spandsp/private/logging.h"
46 #include "spandsp/private/schedule.h"
47 
span_schedule_event(span_sched_state_t * s,int us,span_sched_callback_func_t function,void * user_data)48 SPAN_DECLARE(int) span_schedule_event(span_sched_state_t *s, int us, span_sched_callback_func_t function, void *user_data)
49 {
50     int i;
51 
52     for (i = 0;  i < s->max_to_date;  i++)
53     {
54         if (s->sched[i].callback == NULL)
55             break;
56         /*endif*/
57     }
58     /*endfor*/
59     if (i >= s->allocated)
60     {
61         s->allocated += 5;
62         s->sched = (span_sched_t *) span_realloc(s->sched, sizeof(span_sched_t)*s->allocated);
63     }
64     /*endif*/
65     if (i >= s->max_to_date)
66         s->max_to_date = i + 1;
67     /*endif*/
68     s->sched[i].when = s->ticker + us;
69     s->sched[i].callback = function;
70     s->sched[i].user_data = user_data;
71     return i;
72 }
73 /*- End of function --------------------------------------------------------*/
74 
span_schedule_next(span_sched_state_t * s)75 SPAN_DECLARE(uint64_t) span_schedule_next(span_sched_state_t *s)
76 {
77     int i;
78     uint64_t earliest;
79 
80     earliest = ~((uint64_t) 0);
81     for (i = 0;  i < s->max_to_date;  i++)
82     {
83         if (s->sched[i].callback  &&  earliest > s->sched[i].when)
84             earliest = s->sched[i].when;
85         /*endif*/
86     }
87     /*endfor*/
88     return earliest;
89 }
90 /*- End of function --------------------------------------------------------*/
91 
span_schedule_time(span_sched_state_t * s)92 SPAN_DECLARE(uint64_t) span_schedule_time(span_sched_state_t *s)
93 {
94     return s->ticker;
95 }
96 /*- End of function --------------------------------------------------------*/
97 
span_schedule_update(span_sched_state_t * s,int us)98 SPAN_DECLARE(void) span_schedule_update(span_sched_state_t *s, int us)
99 {
100     int i;
101     span_sched_callback_func_t callback;
102     void *user_data;
103 
104     s->ticker += us;
105     for (i = 0;  i < s->max_to_date;  i++)
106     {
107         if (s->sched[i].callback  &&  s->sched[i].when <= s->ticker)
108         {
109             callback = s->sched[i].callback;
110             user_data = s->sched[i].user_data;
111             s->sched[i].callback = NULL;
112             s->sched[i].user_data = NULL;
113             callback(s, user_data);
114         }
115         /*endif*/
116     }
117     /*endfor*/
118 }
119 /*- End of function --------------------------------------------------------*/
120 
span_schedule_del(span_sched_state_t * s,int i)121 SPAN_DECLARE(void) span_schedule_del(span_sched_state_t *s, int i)
122 {
123     if (i >= s->max_to_date
124         ||
125         i < 0
126         ||
127         s->sched[i].callback == NULL)
128     {
129         span_log(&s->logging, SPAN_LOG_WARNING, "Requested to delete invalid scheduled ID %d ?\n", i);
130         return;
131     }
132     /*endif*/
133     s->sched[i].callback = NULL;
134 }
135 /*- End of function --------------------------------------------------------*/
136 
span_schedule_init(span_sched_state_t * s)137 SPAN_DECLARE(span_sched_state_t *) span_schedule_init(span_sched_state_t *s)
138 {
139     memset(s, 0, sizeof(*s));
140     span_log_init(&s->logging, SPAN_LOG_NONE, NULL);
141     span_log_set_protocol(&s->logging, "SCHEDULE");
142     return s;
143 }
144 /*- End of function --------------------------------------------------------*/
145 
span_schedule_release(span_sched_state_t * s)146 SPAN_DECLARE(int) span_schedule_release(span_sched_state_t *s)
147 {
148     if (s->sched)
149     {
150         span_free(s->sched);
151         s->sched = NULL;
152     }
153     return 0;
154 }
155 /*- End of function --------------------------------------------------------*/
156 
span_schedule_free(span_sched_state_t * s)157 SPAN_DECLARE(int) span_schedule_free(span_sched_state_t *s)
158 {
159     if (s)
160     {
161         span_schedule_release(s);
162         span_free(s);
163     }
164     return 0;
165 }
166 /*- End of function --------------------------------------------------------*/
167 /*- End of file ------------------------------------------------------------*/
168