aboutsummaryrefslogtreecommitdiff
path: root/src/include/gnunet_scheduler_lib.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/gnunet_scheduler_lib.h')
-rw-r--r--src/include/gnunet_scheduler_lib.h442
1 files changed, 442 insertions, 0 deletions
diff --git a/src/include/gnunet_scheduler_lib.h b/src/include/gnunet_scheduler_lib.h
new file mode 100644
index 000000000..aa5830942
--- /dev/null
+++ b/src/include/gnunet_scheduler_lib.h
@@ -0,0 +1,442 @@
1/*
2 This file is part of GNUnet
3 (C) 2009 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21/**
22 * @file include/gnunet_scheduler_lib.h
23 * @brief API to schedule computations using continuation passing style
24 * @author Christian Grothoff
25 */
26
27#ifndef GNUNET_SCHEDULER_LIB_H
28#define GNUNET_SCHEDULER_LIB_H
29
30#ifdef __cplusplus
31extern "C"
32{
33#if 0 /* keep Emacsens' auto-indent happy */
34}
35#endif
36#endif
37
38#include "gnunet_time_lib.h"
39
40
41/**
42 * Opaque handle for the scheduling service.
43 */
44struct GNUNET_SCHEDULER_Handle;
45
46
47/**
48 * Opaque reference to a task.
49 */
50typedef unsigned long long GNUNET_SCHEDULER_TaskIdentifier;
51
52
53/**
54 * Constant used to indicate that the scheduled
55 * task has no others as prerequisites.
56 */
57#define GNUNET_SCHEDULER_NO_PREREQUISITE_TASK ((GNUNET_SCHEDULER_TaskIdentifier) 0)
58
59/**
60 * Reasons why the schedule may have triggered
61 * the task now.
62 */
63enum GNUNET_SCHEDULER_Reason
64{
65 /**
66 * This is the very first task run during startup.
67 */
68 GNUNET_SCHEDULER_REASON_STARTUP = 0,
69
70 /**
71 * We are shutting down and are running all shutdown-related tasks
72 * (regardless of timeout, etc.).
73 */
74 GNUNET_SCHEDULER_REASON_SHUTDOWN = 1,
75
76 /**
77 * The specified timeout has expired.
78 * (also set if the delay given was 0).
79 */
80 GNUNET_SCHEDULER_REASON_TIMEOUT = 2,
81
82 /**
83 * The reading socket is ready.
84 */
85 GNUNET_SCHEDULER_REASON_READ_READY = 4,
86
87 /**
88 * The writing socket is ready.
89 */
90 GNUNET_SCHEDULER_REASON_WRITE_READY = 8,
91
92 /**
93 * The prerequisite task is done.
94 */
95 GNUNET_SCHEDULER_REASON_PREREQ_DONE = 16
96};
97
98
99/**
100 * Valid task priorities. Use these, do not
101 * pass random integers!
102 */
103enum GNUNET_SCHEDULER_Priority
104{
105 /**
106 * Run with the same priority as the current job.
107 */
108 GNUNET_SCHEDULER_PRIORITY_KEEP = 0,
109
110 /**
111 * Run when otherwise idle.
112 */
113 GNUNET_SCHEDULER_PRIORITY_IDLE = 1,
114
115 /**
116 * Run as background job (higher than idle,
117 * lower than default).
118 */
119 GNUNET_SCHEDULER_PRIORITY_BACKGROUND = 2,
120
121 /**
122 * Run with the default priority (normal
123 * P2P operations). Higher than BACKGROUND.
124 */
125 GNUNET_SCHEDULER_PRIORITY_DEFAULT = 3,
126
127 /**
128 * Run with high priority (important requests).
129 * Higher than DEFAULT.
130 */
131 GNUNET_SCHEDULER_PRIORITY_HIGH = 4,
132
133 /**
134 * Run with priority for interactive tasks.
135 * Higher than "HIGH".
136 */
137 GNUNET_SCHEDULER_PRIORITY_UI = 5,
138
139 /**
140 * Run with priority for urgent tasks. Use
141 * for things like aborts and shutdowns that
142 * need to preempt "UI"-level tasks.
143 * Higher than "UI".
144 */
145 GNUNET_SCHEDULER_PRIORITY_URGENT = 6,
146
147 /**
148 * Number of priorities (must be the last priority).
149 * This priority must not be used by clients.
150 */
151 GNUNET_SCHEDULER_PRIORITY_COUNT = 7
152};
153
154
155/**
156 * Context information passed to each scheduler task.
157 */
158struct GNUNET_SCHEDULER_TaskContext
159{
160
161 /**
162 * Scheduler running the task
163 */
164 struct GNUNET_SCHEDULER_Handle *sched;
165
166 /**
167 * Reason why the task is run now
168 */
169 enum GNUNET_SCHEDULER_Reason reason;
170
171 /**
172 * Set of file descriptors ready for reading;
173 * note that additional bits may be set
174 * that were not in the original request
175 */
176 const fd_set *read_ready;
177
178 /**
179 * Set of file descriptors ready for writing;
180 * note that additional bits may be set
181 * that were not in the original request.
182 */
183 const fd_set *write_ready;
184
185};
186
187
188/**
189 * Signature of the main function of a task.
190 *
191 * @param cls closure
192 * @param tc context information (why was this task triggered now)
193 */
194typedef void (*GNUNET_SCHEDULER_Task) (void *cls,
195 const struct
196 GNUNET_SCHEDULER_TaskContext * tc);
197
198
199/**
200 * Initialize and run scheduler. This function will return when
201 * either a shutdown was initiated (via signal) and all tasks marked
202 * to "run_on_shutdown" have been completed or when all tasks in
203 * general have been completed.
204 *
205 * @param task task to run immediately
206 * @param cls closure of task
207 */
208void GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_Task task, void *cls);
209
210
211/**
212 * Request the shutdown of a scheduler. This function can be used to
213 * stop a scheduler, for example from within the signal
214 * handler for signals causing shutdowns.
215 */
216void GNUNET_SCHEDULER_shutdown (struct GNUNET_SCHEDULER_Handle *sched);
217
218
219/**
220 * Get information about the current load of this scheduler. Use this
221 * function to determine if an elective task should be added or simply
222 * dropped (if the decision should be made based on the number of
223 * tasks ready to run).
224 *
225 * @param sched scheduler to query
226 * @param p priority-level to query, use KEEP to query the level
227 * of the current task, use COUNT to get the sum over
228 * all priority levels
229 * @return number of tasks pending right now
230 */
231unsigned int GNUNET_SCHEDULER_get_load (struct GNUNET_SCHEDULER_Handle *sched,
232 enum GNUNET_SCHEDULER_Priority p);
233
234
235/**
236 * Cancel the task with the specified identifier.
237 * The task must not yet have run.
238 *
239 * @param sched scheduler to use
240 * @param task id of the task to cancel
241 * @return the closure of the callback of the cancelled task
242 */
243void *GNUNET_SCHEDULER_cancel (struct GNUNET_SCHEDULER_Handle *sched,
244 GNUNET_SCHEDULER_TaskIdentifier task);
245
246
247/**
248 * Continue the current execution with the given function. This is
249 * similar to the other "add" functions except that there is no delay
250 * and the reason code can be specified.
251 *
252 * @param sched scheduler to use
253 * @param main main function of the task
254 * @param cls closure of task
255 * @param reason reason for task invocation
256 */
257void
258GNUNET_SCHEDULER_add_continuation (struct GNUNET_SCHEDULER_Handle *sched,
259 int run_on_shutdown,
260 GNUNET_SCHEDULER_Task main,
261 void *cls,
262 enum GNUNET_SCHEDULER_Reason reason);
263
264
265/**
266 * Schedule a new task to be run after the specified
267 * prerequisite task has completed.
268 *
269 * @param sched scheduler to use
270 * @param run_on_shutdown run on shutdown?
271 * @param prio how important is this task?
272 * @param prerequisite_task run this task after the task with the given
273 * task identifier completes (and any of our other
274 * conditions, such as delay, read or write-readyness
275 * are satisfied). Use GNUNET_SCHEDULER_NO_PREREQUISITE_TASK to not have any dependency
276 * on completion of other tasks.
277 * @param main main function of the task
278 * @param cls closure of task
279 * @return unique task identifier for the job
280 * only valid until "main" is started!
281 */
282GNUNET_SCHEDULER_TaskIdentifier
283GNUNET_SCHEDULER_add_after (struct GNUNET_SCHEDULER_Handle *sched,
284 int run_on_shutdown,
285 enum GNUNET_SCHEDULER_Priority prio,
286 GNUNET_SCHEDULER_TaskIdentifier prerequisite_task,
287 GNUNET_SCHEDULER_Task main, void *cls);
288
289
290/**
291 * Schedule a new task to be run with a specified delay. The task
292 * will be scheduled for execution once the delay has expired and the
293 * prerequisite task has completed.
294 *
295 * @param sched scheduler to use
296 * @param run_on_shutdown run on shutdown? You can use this
297 * argument to run a function only during shutdown
298 * by setting delay to -1. Set this
299 * argument to GNUNET_NO to skip this task if
300 * the user requested process termination.
301 * @param prio how important is this task?
302 * @param prerequisite_task run this task after the task with the given
303 * task identifier completes (and any of our other
304 * conditions, such as delay, read or write-readyness
305 * are satisfied). Use GNUNET_SCHEDULER_NO_PREREQUISITE_TASK to not have any dependency
306 * on completion of other tasks.
307 * @param delay how long should we wait? Use GNUNET_TIME_UNIT_FOREVER_REL for "forever"
308 * @param main main function of the task
309 * @param cls closure of task
310 * @return unique task identifier for the job
311 * only valid until "main" is started!
312 */
313GNUNET_SCHEDULER_TaskIdentifier
314GNUNET_SCHEDULER_add_delayed (struct GNUNET_SCHEDULER_Handle *sched,
315 int run_on_shutdown,
316 enum GNUNET_SCHEDULER_Priority prio,
317 GNUNET_SCHEDULER_TaskIdentifier
318 prerequisite_task,
319 struct GNUNET_TIME_Relative delay,
320 GNUNET_SCHEDULER_Task main, void *cls);
321
322
323/**
324 * Schedule a new task to be run with a specified delay or when the
325 * specified file descriptor is ready for reading. The delay can be
326 * used as a timeout on the socket being ready. The task will be
327 * scheduled for execution once either the delay has expired or the
328 * socket operation is ready.
329 *
330 * @param sched scheduler to use
331 * @param run_on_shutdown run on shutdown? Set this
332 * argument to GNUNET_NO to skip this task if
333 * the user requested process termination.
334 * @param prio how important is this task?
335 * @param prerequisite_task run this task after the task with the given
336 * task identifier completes (and any of our other
337 * conditions, such as delay, read or write-readyness
338 * are satisfied). Use GNUNET_SCHEDULER_NO_PREREQUISITE_TASK to not have any dependency
339 * on completion of other tasks.
340 * @param delay how long should we wait? Use GNUNET_TIME_UNIT_FOREVER_REL for "forever"
341 * @param rfd read file-descriptor
342 * @param main main function of the task
343 * @param cls closure of task
344 * @return unique task identifier for the job
345 * only valid until "main" is started!
346 */
347GNUNET_SCHEDULER_TaskIdentifier
348GNUNET_SCHEDULER_add_read (struct GNUNET_SCHEDULER_Handle *sched,
349 int run_on_shutdown,
350 enum GNUNET_SCHEDULER_Priority prio,
351 GNUNET_SCHEDULER_TaskIdentifier prerequisite_task,
352 struct GNUNET_TIME_Relative delay,
353 int rfd, GNUNET_SCHEDULER_Task main, void *cls);
354
355
356/**
357 * Schedule a new task to be run with a specified delay or when the
358 * specified file descriptor is ready for writing. The delay can be
359 * used as a timeout on the socket being ready. The task will be
360 * scheduled for execution once either the delay has expired or the
361 * socket operation is ready.
362 *
363 * @param sched scheduler to use
364 * @param run_on_shutdown run on shutdown? Set this
365 * argument to GNUNET_NO to skip this task if
366 * the user requested process termination.
367 * @param prio how important is this task?
368 * @param prerequisite_task run this task after the task with the given
369 * task identifier completes (and any of our other
370 * conditions, such as delay, read or write-readyness
371 * are satisfied). Use GNUNET_SCHEDULER_NO_PREREQUISITE_TASK to not have any dependency
372 * on completion of other tasks.
373 * @param delay how long should we wait? Use GNUNET_TIME_UNIT_FOREVER_REL for "forever"
374 * @param wfd write file-descriptor
375 * @param main main function of the task
376 * @param cls closure of task
377 * @return unique task identifier for the job
378 * only valid until "main" is started!
379 */
380GNUNET_SCHEDULER_TaskIdentifier
381GNUNET_SCHEDULER_add_write (struct GNUNET_SCHEDULER_Handle *sched,
382 int run_on_shutdown,
383 enum GNUNET_SCHEDULER_Priority prio,
384 GNUNET_SCHEDULER_TaskIdentifier prerequisite_task,
385 struct GNUNET_TIME_Relative delay,
386 int wfd, GNUNET_SCHEDULER_Task main, void *cls);
387
388
389/**
390 * Schedule a new task to be run with a specified delay or when any of
391 * the specified file descriptor sets is ready. The delay can be used
392 * as a timeout on the socket(s) being ready. The task will be
393 * scheduled for execution once either the delay has expired or any of
394 * the socket operations is ready. This is the most general
395 * function of the "add" family. Note that the "prerequisite_task"
396 * must be satisfied in addition to any of the other conditions. In
397 * other words, the task will be started when
398 * <code>
399 * (prerequisite-run)
400 * && (delay-ready
401 * || any-rs-ready
402 * || any-ws-ready
403 * || (shutdown-active && run-on-shutdown) )
404 * </code>
405 *
406 * @param sched scheduler to use
407 * @param run_on_shutdown run on shutdown? Set this
408 * argument to GNUNET_NO to skip this task if
409 * the user requested process termination.
410 * @param prio how important is this task?
411 * @param prerequisite_task run this task after the task with the given
412 * task identifier completes (and any of our other
413 * conditions, such as delay, read or write-readyness
414 * are satisfied). Use GNUNET_SCHEDULER_NO_PREREQUISITE_TASK to not have any dependency
415 * on completion of other tasks.
416 * @param delay how long should we wait? Use GNUNET_TIME_UNIT_FOREVER_REL for "forever"
417 * @param nfds highest-numbered file descriptor in any of the two sets plus one
418 * @param rs set of file descriptors we want to read (can be NULL)
419 * @param ws set of file descriptors we want to write (can be NULL)
420 * @param main main function of the task
421 * @param cls closure of task
422 * @return unique task identifier for the job
423 * only valid until "main" is started!
424 */
425GNUNET_SCHEDULER_TaskIdentifier
426GNUNET_SCHEDULER_add_select (struct GNUNET_SCHEDULER_Handle *sched,
427 int run_on_shutdown,
428 enum GNUNET_SCHEDULER_Priority prio,
429 GNUNET_SCHEDULER_TaskIdentifier
430 prerequisite_task,
431 struct GNUNET_TIME_Relative delay,
432 int nfds, const fd_set * rs, const fd_set * ws,
433 GNUNET_SCHEDULER_Task main, void *cls);
434
435#if 0 /* keep Emacsens' auto-indent happy */
436{
437#endif
438#ifdef __cplusplus
439}
440#endif
441
442#endif