NetSurf
schedule.c
Go to the documentation of this file.
1/*
2 * Copyright 2008 Vincent Sanders <vince@simtec.co.uk>
3 *
4 * This file is part of NetSurf, http://www.netsurf-browser.org/
5 *
6 * NetSurf is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * NetSurf is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <stdlib.h>
20#include <time.h>
21
22#include "utils/sys_time.h"
23#include "utils/log.h"
24#include "utils/errors.h"
25
26#include "windows/schedule.h"
27
28/* linked list of scheduled callbacks */
29static struct nscallback *schedule_list = NULL;
30
31/**
32 * scheduled callback.
33 */
34struct nscallback
35{
36 struct nscallback *next;
37 struct timeval tv;
38 void (*callback)(void *p);
39 void *p;
40};
41
42
43/**
44 * Unschedule a callback.
45 *
46 * \param callback callback function
47 * \param p user parameter, passed to callback function
48 *
49 * All scheduled callbacks matching both callback and p are removed.
50 */
51
52static nserror schedule_remove(void (*callback)(void *p), void *p)
53{
54 struct nscallback *cur_nscb;
55 struct nscallback *prev_nscb;
56 struct nscallback *unlnk_nscb;
57
58 /* check there is something on the list to remove */
59 if (schedule_list == NULL) {
60 return NSERROR_OK;
61 }
62
63 NSLOG(schedule, DEBUG, "removing %p, %p", callback, p);
64
65 cur_nscb = schedule_list;
66 prev_nscb = NULL;
67
68 while (cur_nscb != NULL) {
69 if ((cur_nscb->callback == callback) &&
70 (cur_nscb->p == p)) {
71 /* item to remove */
72
73 NSLOG(schedule, DEBUG,
74 "callback entry %p removing %p(%p)",
75 cur_nscb,
76 cur_nscb->callback,
77 cur_nscb->p);
78
79 /* remove callback */
80 unlnk_nscb = cur_nscb;
81 cur_nscb = unlnk_nscb->next;
82
83 if (prev_nscb == NULL) {
84 schedule_list = cur_nscb;
85 } else {
86 prev_nscb->next = cur_nscb;
87 }
88 free (unlnk_nscb);
89 } else {
90 /* move to next element */
91 prev_nscb = cur_nscb;
92 cur_nscb = prev_nscb->next;
93 }
94 }
95 return NSERROR_OK;
96}
97
98/* exported interface documented in windows/schedule.h */
99nserror win32_schedule(int ival, void (*callback)(void *p), void *p)
100{
101 struct nscallback *nscb;
102 struct timeval tv;
103 nserror ret;
104
105 ret = schedule_remove(callback, p);
106 if ((ival < 0) || (ret != NSERROR_OK)) {
107 return ret;
108 }
109
110 tv.tv_sec = ival / 1000; /* miliseconds to seconds */
111 tv.tv_usec = (ival % 1000) * 1000; /* remainder to microseconds */
112
113 nscb = calloc(1, sizeof(struct nscallback));
114 if (nscb == NULL) {
115 return NSERROR_NOMEM;
116 }
117
118 NSLOG(schedule, DEBUG,
119 "adding callback %p for %p(%p) at %d cs",
120 nscb, callback, p, ival);
121
122 gettimeofday(&nscb->tv, NULL);
123 timeradd(&nscb->tv, &tv, &nscb->tv);
124
125 nscb->callback = callback;
126 nscb->p = p;
127
128 /* add to list front */
129 nscb->next = schedule_list;
130 schedule_list = nscb;
131
132 return NSERROR_OK;
133}
134
135/* exported interface documented in schedule.h */
136int
138{
139 struct timeval tv;
140 struct timeval nexttime;
141 struct timeval rettime;
142 struct nscallback *cur_nscb;
143 struct nscallback *prev_nscb;
144 struct nscallback *unlnk_nscb;
145
146 if (schedule_list == NULL)
147 return -1;
148
149 /* reset enumeration to the start of the list */
150 cur_nscb = schedule_list;
151 prev_nscb = NULL;
152 nexttime = cur_nscb->tv;
153
154 gettimeofday(&tv, NULL);
155
156 while (cur_nscb != NULL) {
157 if (timercmp(&tv, &cur_nscb->tv, >)) {
158 /* scheduled time */
159
160 /* remove callback */
161 unlnk_nscb = cur_nscb;
162
163 if (prev_nscb == NULL) {
164 schedule_list = unlnk_nscb->next;
165 } else {
166 prev_nscb->next = unlnk_nscb->next;
167 }
168
169 NSLOG(schedule, DEBUG,
170 "callback entry %p running %p(%p)",
171 unlnk_nscb,
172 unlnk_nscb->callback,
173 unlnk_nscb->p);
174 /* call callback */
175 unlnk_nscb->callback(unlnk_nscb->p);
176
177 free(unlnk_nscb);
178
179 /* dispatched events can modify the list,
180 * instead of locking we simply reset list
181 * enumeration to the start.
182 */
183 if (schedule_list == NULL)
184 return -1; /* no more callbacks scheduled */
185
186 cur_nscb = schedule_list;
187 prev_nscb = NULL;
188 nexttime = cur_nscb->tv;
189 } else {
190 /* if the time to the event is sooner than the
191 * currently recorded soonest event record it
192 */
193 if (timercmp(&nexttime, &cur_nscb->tv, >)) {
194 nexttime = cur_nscb->tv;
195 }
196 /* move to next element */
197 prev_nscb = cur_nscb;
198 cur_nscb = prev_nscb->next;
199 }
200 }
201
202 /* make returned time relative to now */
203 timersub(&nexttime, &tv, &rettime);
204
205 NSLOG(schedule, DEBUG,
206 "returning time to next event as %ldms",
207 (rettime.tv_sec * 1000) + (rettime.tv_usec / 1000));
208
209 /* return next event time in milliseconds (24days max wait) */
210 return (rettime.tv_sec * 1000) + (rettime.tv_usec / 1000);
211}
212
213/* exported interface documented in schedule.h */
215{
216 struct timeval tv;
217 struct nscallback *cur_nscb;
218
219 gettimeofday(&tv, NULL);
220
221 NSLOG(netsurf, INFO, "schedule list at %ld:%ld", tv.tv_sec, tv.tv_usec);
222
223 cur_nscb = schedule_list;
224
225 while (cur_nscb != NULL) {
226 NSLOG(netsurf, INFO,
227 "Schedule %p at %ld:%ld",
228 cur_nscb,
229 cur_nscb->tv.tv_sec,
230 cur_nscb->tv.tv_usec);
231 cur_nscb = cur_nscb->next;
232 }
233}
234
235
236/*
237 * Local Variables:
238 * c-basic-offset:8
239 * End:
240 */
void list_schedule(void)
LOG all current scheduled events.
Definition: schedule.c:210
int schedule_run(void)
Process events up to current time.
Definition: schedule.c:137
Error codes.
nserror
Enumeration of error codes.
Definition: errors.h:29
@ NSERROR_NOMEM
Memory exhaustion.
Definition: errors.h:32
@ NSERROR_OK
No error.
Definition: errors.h:30
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
scheduled callback.
Definition: schedule.c:37
struct nscallback * next
Definition: schedule.c:40
struct TimeVal tv
Definition: schedule.c:39
void *restrict p
Definition: schedule.c:41
void *restrict callback
Definition: schedule.c:40
BSD style timeval macros.
#define timercmp(a, aa, cmp)
Definition: sys_time.h:66
#define timeradd(a, aa, result)
Definition: sys_time.h:42
#define timersub(a, aa, result)
Definition: sys_time.h:54
Interface to time operations.
static struct nscallback * schedule_list
Definition: schedule.c:29
static nserror schedule_remove(void(*callback)(void *p), void *p)
Unschedule a callback.
Definition: schedule.c:52
nserror win32_schedule(int ival, void(*callback)(void *p), void *p)
Schedule a callback.
Definition: schedule.c:99