missing function reference
[oweals/gnunet.git] / src / include / gnunet_scheduler_lib.h
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
31 extern "C"
32 {
33 #if 0                           /* keep Emacsens' auto-indent happy */
34 }
35 #endif
36 #endif
37
38
39 /**
40  * Opaque handle for the scheduling service.
41  */
42 struct GNUNET_SCHEDULER_Handle;
43
44 /**
45  * Opaque reference to a task.
46  */
47 typedef unsigned long long GNUNET_SCHEDULER_TaskIdentifier;
48
49
50 /**
51  * Constant used to indicate that the scheduled
52  * task has no others as prerequisites.
53  */
54 #define GNUNET_SCHEDULER_NO_TASK ((GNUNET_SCHEDULER_TaskIdentifier) 0)
55
56 /**
57  * Reasons why the schedule may have triggered
58  * the task now.
59  */
60 enum GNUNET_SCHEDULER_Reason
61 {
62   /**
63    * This is the very first task run during startup.
64    */
65   GNUNET_SCHEDULER_REASON_STARTUP = 0,
66
67   /**
68    * We are shutting down and are running all shutdown-related tasks
69    * (regardless of timeout, etc.).
70    */
71   GNUNET_SCHEDULER_REASON_SHUTDOWN = 1,
72
73   /**
74    * The specified timeout has expired.
75    * (also set if the delay given was 0).
76    */
77   GNUNET_SCHEDULER_REASON_TIMEOUT = 2,
78
79   /**
80    * The reading socket is ready.
81    */
82   GNUNET_SCHEDULER_REASON_READ_READY = 4,
83
84   /**
85    * The writing socket is ready.
86    */
87   GNUNET_SCHEDULER_REASON_WRITE_READY = 8,
88
89   /**
90    * The prerequisite task is done.
91    */
92   GNUNET_SCHEDULER_REASON_PREREQ_DONE = 16
93 };
94
95
96 /**
97  * Valid task priorities.  Use these, do not
98  * pass random integers!
99  */
100 enum GNUNET_SCHEDULER_Priority
101 {
102   /**
103    * Run with the same priority as the current job.
104    */
105   GNUNET_SCHEDULER_PRIORITY_KEEP = 0,
106
107   /**
108    * Run when otherwise idle.
109    */
110   GNUNET_SCHEDULER_PRIORITY_IDLE = 1,
111
112   /**
113    * Run as background job (higher than idle,
114    * lower than default).
115    */
116   GNUNET_SCHEDULER_PRIORITY_BACKGROUND = 2,
117
118   /**
119    * Run with the default priority (normal
120    * P2P operations).  Higher than BACKGROUND.
121    */
122   GNUNET_SCHEDULER_PRIORITY_DEFAULT = 3,
123
124   /**
125    * Run with high priority (important requests).
126    * Higher than DEFAULT.
127    */
128   GNUNET_SCHEDULER_PRIORITY_HIGH = 4,
129
130   /**
131    * Run with priority for interactive tasks.
132    * Higher than "HIGH".
133    */
134   GNUNET_SCHEDULER_PRIORITY_UI = 5,
135
136   /**
137    * Run with priority for urgent tasks.  Use
138    * for things like aborts and shutdowns that
139    * need to preempt "UI"-level tasks.
140    * Higher than "UI".
141    */
142   GNUNET_SCHEDULER_PRIORITY_URGENT = 6,
143
144   /**
145    * Number of priorities (must be the last priority).
146    * This priority must not be used by clients.
147    */
148   GNUNET_SCHEDULER_PRIORITY_COUNT = 7
149 };
150
151 #include "gnunet_time_lib.h"
152 #include "gnunet_network_lib.h"
153
154
155 /**
156  * Context information passed to each scheduler task.
157  */
158 struct 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 struct GNUNET_NETWORK_FDSet *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 struct GNUNET_NETWORK_FDSet *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  */
194 typedef 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 all
201  * tasks have completed.  On systems with signals, receiving a SIGTERM
202  * (and other similar signals) will cause "GNUNET_SCHEDULER_shutdown"
203  * to be run after the active task is complete.  As a result, SIGTERM
204  * causes all active tasks to be scheduled with reason
205  * "GNUNET_SCHEDULER_REASON_SHUTDOWN".  (However, tasks added
206  * afterwards will execute normally!).  Note that any particular
207  * signal will only shut down one scheduler; applications should
208  * always only create a single scheduler.
209  *
210  * @param task task to run first (and immediately)
211  * @param task_cls closure of task
212  */
213 void GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_Task task, void *task_cls);
214
215
216 /**
217  * Request the shutdown of a scheduler.  Marks all currently
218  * pending tasks as ready because of shutdown.  This will
219  * cause all tasks to run (as soon as possible, respecting
220  * priorities and prerequisite tasks).  Note that tasks
221  * scheduled AFTER this call may still be delayed arbitrarily.
222  *
223  * @param sched the scheduler
224  */
225 void GNUNET_SCHEDULER_shutdown (struct GNUNET_SCHEDULER_Handle *sched);
226
227
228 /**
229  * Get information about the current load of this scheduler.  Use this
230  * function to determine if an elective task should be added or simply
231  * dropped (if the decision should be made based on the number of
232  * tasks ready to run).
233  *
234  * @param sched scheduler to query
235  * @param p priority-level to query, use KEEP to query the level
236  *          of the current task, use COUNT to get the sum over
237  *          all priority levels
238  * @return number of tasks pending right now
239  */
240 unsigned int GNUNET_SCHEDULER_get_load (struct GNUNET_SCHEDULER_Handle *sched,
241                                         enum GNUNET_SCHEDULER_Priority p);
242
243
244 /**
245  * Obtain the reason code for why the current task was
246  * started.  Will return the same value as 
247  * the GNUNET_SCHEDULER_TaskContext's reason field.
248  *
249  * @param sched scheduler to query
250  * @return reason(s) why the current task is run
251  */
252 enum GNUNET_SCHEDULER_Reason
253 GNUNET_SCHEDULER_get_reason (struct GNUNET_SCHEDULER_Handle *sched);
254
255
256 /**
257  * Cancel the task with the specified identifier.
258  * The task must not yet have run.
259  *
260  * @param sched scheduler to use
261  * @param task id of the task to cancel
262  * @return the closure of the callback of the cancelled task
263  */
264 void *GNUNET_SCHEDULER_cancel (struct GNUNET_SCHEDULER_Handle *sched,
265                                GNUNET_SCHEDULER_TaskIdentifier task);
266
267
268 /**
269  * Continue the current execution with the given function.  This is
270  * similar to the other "add" functions except that there is no delay
271  * and the reason code can be specified.
272  *
273  * @param sched scheduler to use
274  * @param task main function of the task
275  * @param task_cls closure of task
276  * @param reason reason for task invocation
277  */
278 void
279 GNUNET_SCHEDULER_add_continuation (struct GNUNET_SCHEDULER_Handle *sched,
280                                    GNUNET_SCHEDULER_Task task,
281                                    void *task_cls,
282                                    enum GNUNET_SCHEDULER_Reason reason);
283
284
285 /**
286  * Schedule a new task to be run after the specified prerequisite task
287  * has completed. It will be run with the priority of the calling
288  * task.
289  *
290  * @param sched scheduler to use
291  * @param prerequisite_task run this task after the task with the given
292  *        task identifier completes (and any of our other
293  *        conditions, such as delay, read or write-readiness
294  *        are satisfied).  Use  GNUNET_SCHEDULER_NO_TASK to not have any dependency
295  *        on completion of other tasks (this will cause the task to run as
296  *        soon as possible).
297  * @param task main function of the task
298  * @param task_cls closure of task
299  * @return unique task identifier for the job
300  *         only valid until "task" is started!
301  */
302 GNUNET_SCHEDULER_TaskIdentifier
303 GNUNET_SCHEDULER_add_after (struct GNUNET_SCHEDULER_Handle *sched,
304                             GNUNET_SCHEDULER_TaskIdentifier prerequisite_task,
305                             GNUNET_SCHEDULER_Task task,
306                             void *task_cls);
307
308
309 /**
310  * Schedule a new task to be run with a specified priority.
311  *
312  * @param sched scheduler to use
313  * @param prio how important is the new task?
314  * @param task main function of the task
315  * @param task_cls closure of task
316  * @return unique task identifier for the job
317  *         only valid until "task" is started!
318  */
319 GNUNET_SCHEDULER_TaskIdentifier
320 GNUNET_SCHEDULER_add_with_priority (struct GNUNET_SCHEDULER_Handle *sched,
321                                     enum GNUNET_SCHEDULER_Priority prio,
322                                     GNUNET_SCHEDULER_Task task,
323                                     void *task_cls);
324
325
326 /**
327  * Schedule a new task to be run as soon as possible. The task
328  * will be run with the priority of the calling task.
329  *
330  * @param sched scheduler to use
331  * @param task main function of the task
332  * @param task_cls closure of task
333  * @return unique task identifier for the job
334  *         only valid until "task" is started!
335  */
336 GNUNET_SCHEDULER_TaskIdentifier
337 GNUNET_SCHEDULER_add_now (struct GNUNET_SCHEDULER_Handle *sched,
338                           GNUNET_SCHEDULER_Task task,
339                           void *task_cls);
340
341
342 /**
343  * Schedule a new task to be run with a specified delay.  The task
344  * will be scheduled for execution once the delay has expired. It
345  * will be run with the priority of the calling task.
346  *
347  * @param sched scheduler to use
348  * @param delay when should this operation time out? Use 
349  *        GNUNET_TIME_UNIT_FOREVER_REL for "on shutdown"
350  * @param task main function of the task
351  * @param task_cls closure of task
352  * @return unique task identifier for the job
353  *         only valid until "task" is started!
354  */
355 GNUNET_SCHEDULER_TaskIdentifier
356 GNUNET_SCHEDULER_add_delayed (struct GNUNET_SCHEDULER_Handle *sched,
357                               struct GNUNET_TIME_Relative delay,
358                               GNUNET_SCHEDULER_Task task,
359                               void *task_cls);
360
361
362 /**
363  * Schedule a new task to be run with a specified delay or when the
364  * specified file descriptor is ready for reading.  The delay can be
365  * used as a timeout on the socket being ready.  The task will be
366  * scheduled for execution once either the delay has expired or the
367  * socket operation is ready.  It will be run with the priority of
368  * the calling task.
369  *
370  * @param sched scheduler to use
371  * @param delay when should this operation time out? Use 
372  *        GNUNET_TIME_UNIT_FOREVER_REL for "on shutdown"
373  * @param rfd read file-descriptor
374  * @param task main function of the task
375  * @param task_cls closure of task
376  * @return unique task identifier for the job
377  *         only valid until "task" is started!
378  */
379 GNUNET_SCHEDULER_TaskIdentifier
380 GNUNET_SCHEDULER_add_read_net (struct GNUNET_SCHEDULER_Handle *sched,
381                                struct GNUNET_TIME_Relative delay,
382                                struct GNUNET_NETWORK_Handle *rfd,
383                                GNUNET_SCHEDULER_Task task,
384                                void *task_cls);
385
386
387 /**
388  * Schedule a new task to be run with a specified delay or when the
389  * specified file descriptor is ready for writing.  The delay can be
390  * used as a timeout on the socket being ready.  The task will be
391  * scheduled for execution once either the delay has expired or the
392  * socket operation is ready.  It will be run with the priority of
393  * the calling task.
394  *
395  * @param sched scheduler to use
396  * @param delay when should this operation time out? Use 
397  *        GNUNET_TIME_UNIT_FOREVER_REL for "on shutdown"
398  * @param wfd write file-descriptor
399  * @param task main function of the task
400  * @param task_cls closure of task
401  * @return unique task identifier for the job
402  *         only valid until "task" is started!
403  */
404 GNUNET_SCHEDULER_TaskIdentifier
405 GNUNET_SCHEDULER_add_write_net (struct GNUNET_SCHEDULER_Handle *sched,
406                                 struct GNUNET_TIME_Relative delay,
407                                 struct GNUNET_NETWORK_Handle *wfd, 
408                                 GNUNET_SCHEDULER_Task task, 
409                                 void *task_cls);
410
411
412 /**
413  * Schedule a new task to be run with a specified delay or when the
414  * specified file descriptor is ready for reading.  The delay can be
415  * used as a timeout on the socket being ready.  The task will be
416  * scheduled for execution once either the delay has expired or the
417  * socket operation is ready. It will be run with the priority of
418  * the calling task.
419  *
420  * @param sched scheduler to use
421  * @param delay when should this operation time out? Use 
422  *        GNUNET_TIME_UNIT_FOREVER_REL for "on shutdown"
423  * @param rfd read file-descriptor
424  * @param task main function of the task
425  * @param task_cls closure of task
426  * @return unique task identifier for the job
427  *         only valid until "task" is started!
428  */
429 GNUNET_SCHEDULER_TaskIdentifier
430 GNUNET_SCHEDULER_add_read_file (struct GNUNET_SCHEDULER_Handle *sched,
431                                 struct GNUNET_TIME_Relative delay,
432                                 const struct GNUNET_DISK_FileHandle *rfd, 
433                                 GNUNET_SCHEDULER_Task task,
434                                 void *task_cls);
435
436
437 /**
438  * Schedule a new task to be run with a specified delay or when the
439  * specified file descriptor is ready for writing.  The delay can be
440  * used as a timeout on the socket being ready.  The task will be
441  * scheduled for execution once either the delay has expired or the
442  * socket operation is ready. It will be run with the priority of
443  * the calling task.
444  *
445  * @param sched scheduler to use
446  * @param delay when should this operation time out? Use 
447  *        GNUNET_TIME_UNIT_FOREVER_REL for "on shutdown"
448  * @param wfd write file-descriptor
449  * @param task main function of the task
450  * @param task_cls closure of task
451  * @return unique task identifier for the job
452  *         only valid until "task" is started!
453  */
454 GNUNET_SCHEDULER_TaskIdentifier
455 GNUNET_SCHEDULER_add_write_file (struct GNUNET_SCHEDULER_Handle *sched,
456                                  struct GNUNET_TIME_Relative delay,
457                                  const struct GNUNET_DISK_FileHandle *wfd,
458                                  GNUNET_SCHEDULER_Task task, 
459                                  void *task_cls);
460
461
462 /**
463  * Schedule a new task to be run with a specified delay or when any of
464  * the specified file descriptor sets is ready.  The delay can be used
465  * as a timeout on the socket(s) being ready.  The task will be
466  * scheduled for execution once either the delay has expired or any of
467  * the socket operations is ready.  This is the most general
468  * function of the "add" family.  Note that the "prerequisite_task"
469  * must be satisfied in addition to any of the other conditions.  In
470  * other words, the task will be started when
471  * <code>
472  * (prerequisite-run)
473  * && (delay-ready
474  *     || any-rs-ready
475  *     || any-ws-ready
476  *     || (shutdown-active && run-on-shutdown) )
477  * </code>
478  *
479  * @param sched scheduler to use
480  * @param prio how important is this task?
481  * @param prerequisite_task run this task after the task with the given
482  *        task identifier completes (and any of our other
483  *        conditions, such as delay, read or write-readiness
484  *        are satisfied).  Use GNUNET_SCHEDULER_NO_TASK to not have any dependency
485  *        on completion of other tasks.
486  * @param delay how long should we wait? Use GNUNET_TIME_UNIT_FOREVER_REL for "forever",
487  *        which means that the task will only be run after we receive SIGTERM
488  * @param rs set of file descriptors we want to read (can be NULL)
489  * @param ws set of file descriptors we want to write (can be NULL)
490  * @param task main function of the task
491  * @param task_cls closure of task
492  * @return unique task identifier for the job
493  *         only valid until "task" is started!
494  */
495 GNUNET_SCHEDULER_TaskIdentifier
496 GNUNET_SCHEDULER_add_select (struct GNUNET_SCHEDULER_Handle *sched,
497                              enum GNUNET_SCHEDULER_Priority prio,
498                              GNUNET_SCHEDULER_TaskIdentifier
499                              prerequisite_task,
500                              struct GNUNET_TIME_Relative delay,
501                              const struct GNUNET_NETWORK_FDSet * rs,
502                              const struct GNUNET_NETWORK_FDSet * ws,
503                              GNUNET_SCHEDULER_Task task, 
504                              void *task_cls);
505
506 #if 0                           /* keep Emacsens' auto-indent happy */
507 {
508 #endif
509 #ifdef __cplusplus
510 }
511 #endif
512
513 #endif