don't run set with valgrind per default
[oweals/gnunet.git] / src / include / gnunet_scheduler_lib.h
1 /*
2       This file is part of GNUnet
3       Copyright (C) 2009-2016 GNUnet e.V.
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 3, 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., 51 Franklin Street, Fifth Floor,
18       Boston, MA 02110-1301, USA.
19  */
20
21 /**
22  * @author Christian Grothoff
23  *
24  * @file
25  * API to schedule computations using continuation passing style
26  *
27  * @defgroup scheduler  Scheduler library
28  * Event loop (scheduler)
29  *
30  * Schedule computations using continuation passing style.
31  *
32  * @{
33  */
34
35 #ifndef GNUNET_SCHEDULER_LIB_H
36 #define GNUNET_SCHEDULER_LIB_H
37
38 #ifdef __cplusplus
39 extern "C"
40 {
41 #if 0                           /* keep Emacsens' auto-indent happy */
42 }
43 #endif
44 #endif
45
46 /**
47  * Opaque reference to a task.
48  */
49 struct GNUNET_SCHEDULER_Task;
50
51 /**
52  * Reasons why the schedule may have triggered
53  * the task now.
54  */
55 enum GNUNET_SCHEDULER_Reason
56 {
57   /**
58    * This task is not ready.
59    */
60   GNUNET_SCHEDULER_REASON_NONE = 0,
61
62   /**
63    * This is the very first task run during startup.
64    */
65   GNUNET_SCHEDULER_REASON_STARTUP = 1,
66
67   /**
68    * We are shutting down and are running all shutdown-related tasks.
69    */
70   GNUNET_SCHEDULER_REASON_SHUTDOWN = 2,
71
72   /**
73    * The specified timeout has expired.
74    * (also set if the delay given was 0).
75    */
76   GNUNET_SCHEDULER_REASON_TIMEOUT = 4,
77
78   /**
79    * The reading socket is ready.
80    */
81   GNUNET_SCHEDULER_REASON_READ_READY = 8,
82
83   /**
84    * The writing socket is ready.
85    */
86   GNUNET_SCHEDULER_REASON_WRITE_READY = 16,
87
88   /**
89    * The prerequisite task is done.
90    */
91   GNUNET_SCHEDULER_REASON_PREREQ_DONE = 32
92 };
93
94
95 #include "gnunet_time_lib.h"
96 #include "gnunet_network_lib.h"
97
98
99 /**
100  * Context information passed to each scheduler task.
101  */
102 struct GNUNET_SCHEDULER_TaskContext
103 {
104   /**
105    * Reason why the task is run now
106    */
107   enum GNUNET_SCHEDULER_Reason reason;
108
109   /**
110    * Set of file descriptors ready for reading;
111    * note that additional bits may be set
112    * that were not in the original request
113    */
114   const struct GNUNET_NETWORK_FDSet *read_ready;
115
116   /**
117    * Set of file descriptors ready for writing;
118    * note that additional bits may be set
119    * that were not in the original request.
120    */
121   const struct GNUNET_NETWORK_FDSet *write_ready;
122
123 };
124
125
126 /**
127  * Signature of the main function of a task.
128  *
129  * @param cls closure
130  * @param tc context information (why was this task triggered now)
131  */
132 typedef void
133 (*GNUNET_SCHEDULER_TaskCallback) (void *cls);
134
135
136 /**
137  * Signature of the select function used by the scheduler.
138  * #GNUNET_NETWORK_socket_select matches it.
139  *
140  * @param cls closure
141  * @param rfds set of sockets to be checked for readability
142  * @param wfds set of sockets to be checked for writability
143  * @param efds set of sockets to be checked for exceptions
144  * @param timeout relative value when to return
145  * @return number of selected sockets, #GNUNET_SYSERR on error
146  */
147 typedef int
148 (*GNUNET_SCHEDULER_select) (void *cls,
149                             struct GNUNET_NETWORK_FDSet *rfds,
150                             struct GNUNET_NETWORK_FDSet *wfds,
151                             struct GNUNET_NETWORK_FDSet *efds,
152                             struct GNUNET_TIME_Relative timeout);
153
154
155 /**
156  * Initialize and run scheduler.  This function will return when all
157  * tasks have completed.  On systems with signals, receiving a SIGTERM
158  * (and other similar signals) will cause #GNUNET_SCHEDULER_shutdown
159  * to be run after the active task is complete.  As a result, SIGTERM
160  * causes all shutdown tasks to be scheduled with reason
161  * #GNUNET_SCHEDULER_REASON_SHUTDOWN.  (However, tasks added
162  * afterwards will execute normally!).  Note that any particular
163  * signal will only shut down one scheduler; applications should
164  * always only create a single scheduler.
165  *
166  * @param task task to run first (and immediately)
167  * @param task_cls closure of @a task
168  */
169 void
170 GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_TaskCallback task,
171                       void *task_cls);
172
173
174 /**
175  * Request the shutdown of a scheduler.  Marks all tasks
176  * awaiting shutdown as ready. Note that tasks
177  * scheduled with #GNUNET_SCHEDULER_add_shutdown() AFTER this call
178  * will be delayed until the next shutdown signal.
179  */
180 void
181 GNUNET_SCHEDULER_shutdown (void);
182
183
184 /**
185  * Get information about the current load of this scheduler.  Use this
186  * function to determine if an elective task should be added or simply
187  * dropped (if the decision should be made based on the number of
188  * tasks ready to run).
189  *
190  * @param p priority-level to query, use KEEP to query the level
191  *          of the current task, use COUNT to get the sum over
192  *          all priority levels
193  * @return number of tasks pending right now
194  */
195 unsigned int
196 GNUNET_SCHEDULER_get_load (enum GNUNET_SCHEDULER_Priority p);
197
198
199 /**
200  * Obtain the reasoning why the current task was
201  * started.
202  *
203  * @return task context with information why the current task is run
204  */
205 const struct GNUNET_SCHEDULER_TaskContext *
206 GNUNET_SCHEDULER_get_task_context (void);
207
208
209 /**
210  * Cancel the task with the specified identifier.
211  * The task must not yet have run.
212  *
213  * @param task id of the task to cancel
214  * @return the closure of the callback of the cancelled task
215  */
216 void *
217 GNUNET_SCHEDULER_cancel (struct GNUNET_SCHEDULER_Task *task);
218
219
220 /**
221  * Continue the current execution with the given function.  This is
222  * similar to the other "add" functions except that there is no delay
223  * and the reason code can be specified.
224  *
225  * @param task main function of the task
226  * @param task_cls closure for @a task
227  * @param reason reason for task invocation
228  * @param priority priority to use for the task
229  */
230 void
231 GNUNET_SCHEDULER_add_with_reason_and_priority (GNUNET_SCHEDULER_TaskCallback task,
232                                                void *task_cls,
233                                                enum GNUNET_SCHEDULER_Reason reason,
234                                                enum GNUNET_SCHEDULER_Priority priority);
235
236
237 /**
238  * Schedule a new task to be run with a specified priority.
239  *
240  * @param prio how important is the new task?
241  * @param task main function of the task
242  * @param task_cls closure of @a task
243  * @return unique task identifier for the job
244  *         only valid until @a task is started!
245  */
246 struct GNUNET_SCHEDULER_Task *
247 GNUNET_SCHEDULER_add_with_priority (enum GNUNET_SCHEDULER_Priority prio,
248                                     GNUNET_SCHEDULER_TaskCallback task,
249                                     void *task_cls);
250
251
252 /**
253  * Schedule a new task to be run as soon as possible. Note that this
254  * does not guarantee that this will be the next task that is being
255  * run, as other tasks with higher priority (or that are already ready
256  * to run) might get to run first.  Just as with delays, clients must
257  * not rely on any particular order of execution between tasks
258  * scheduled concurrently.
259  *
260  * The task will be run with the DEFAULT priority.
261  *
262  * @param task main function of the task
263  * @param task_cls closure of @a task
264  * @return unique task identifier for the job
265  *         only valid until @a task is started!
266  */
267 struct GNUNET_SCHEDULER_Task *
268 GNUNET_SCHEDULER_add_now (GNUNET_SCHEDULER_TaskCallback task,
269                           void *task_cls);
270
271
272 /**
273  * Schedule a new task to be run on shutdown, that is when a CTRL-C
274  * signal is received, or when #GNUNET_SCHEDULER_shutdown() is being
275  * invoked.
276  *
277  * @param task main function of the task
278  * @param task_cls closure of @a task
279  * @return unique task identifier for the job
280  *         only valid until @a task is started!
281  */
282 struct GNUNET_SCHEDULER_Task *
283 GNUNET_SCHEDULER_add_shutdown (GNUNET_SCHEDULER_TaskCallback task,
284                                void *task_cls);
285
286
287 /**
288  * Schedule a new task to be run as soon as possible with the
289  * (transitive) ignore-shutdown flag either explicitly set or
290  * explicitly enabled.  This task (and all tasks created from it,
291  * other than by another call to this function) will either count or
292  * not count for the 'lifeness' of the process.  This API is only
293  * useful in a few special cases.
294  *
295  * @param lifeness #GNUNET_YES if the task counts for lifeness, #GNUNET_NO if not.
296  * @param task main function of the task
297  * @param task_cls closure of @a task
298  * @return unique task identifier for the job
299  *         only valid until @a task is started!
300  */
301 struct GNUNET_SCHEDULER_Task *
302 GNUNET_SCHEDULER_add_now_with_lifeness (int lifeness,
303                                         GNUNET_SCHEDULER_TaskCallback task,
304                                         void *task_cls);
305
306
307 /**
308  * Schedule a new task to be run with a specified delay.  The task
309  * will be scheduled for execution once the delay has expired. It
310  * will be run with the DEFAULT priority.
311  *
312  * @param delay with which the operation should be run
313  * @param task main function of the task
314  * @param task_cls closure of @a task
315  * @return unique task identifier for the job
316  *         only valid until @a task is started!
317  */
318 struct GNUNET_SCHEDULER_Task *
319 GNUNET_SCHEDULER_add_delayed (struct GNUNET_TIME_Relative delay,
320                               GNUNET_SCHEDULER_TaskCallback task,
321                               void *task_cls);
322
323
324 /**
325  * Schedule a new task to be run at the specified time.  The task
326  * will be scheduled for execution once specified time has been
327  * reached. It will be run with the DEFAULT priority.
328  *
329  * @param at time at which this operation should run
330  * @param task main function of the task
331  * @param task_cls closure of @a task
332  * @return unique task identifier for the job
333  *         only valid until @a task is started!
334  */
335 struct GNUNET_SCHEDULER_Task *
336 GNUNET_SCHEDULER_add_at (struct GNUNET_TIME_Absolute at,
337                          GNUNET_SCHEDULER_TaskCallback task,
338                          void *task_cls);
339
340
341 /**
342  * Schedule a new task to be run with a specified delay.  The task
343  * will be scheduled for execution once the delay has expired.
344  *
345  * @param delay when should this operation time out?
346  * @param priority priority to use for the task
347  * @param task main function of the task
348  * @param task_cls closure of @a task
349  * @return unique task identifier for the job
350  *         only valid until @a task is started!
351  */
352 struct GNUNET_SCHEDULER_Task *
353 GNUNET_SCHEDULER_add_delayed_with_priority (struct GNUNET_TIME_Relative delay,
354                                             enum GNUNET_SCHEDULER_Priority priority,
355                                             GNUNET_SCHEDULER_TaskCallback task,
356                                             void *task_cls);
357
358
359 /**
360  * Schedule a new task to be run at the specified time.  The task
361  * will be scheduled for execution at time @a at.
362  *
363  * @param at time when the operation should run
364  * @param priority priority to use for the task
365  * @param task main function of the task
366  * @param task_cls closure of @a task
367  * @return unique task identifier for the job
368  *         only valid until @a task is started!
369  */
370 struct GNUNET_SCHEDULER_Task *
371 GNUNET_SCHEDULER_add_at_with_priority (struct GNUNET_TIME_Absolute at,
372                                        enum GNUNET_SCHEDULER_Priority priority,
373                                        GNUNET_SCHEDULER_TaskCallback task,
374                                        void *task_cls);
375
376
377 /**
378  * Schedule a new task to be run with a specified delay or when the
379  * specified file descriptor is ready for reading.  The delay can be
380  * used as a timeout on the socket being ready.  The task will be
381  * scheduled for execution once either the delay has expired or the
382  * socket operation is ready.  It will be run with the DEFAULT priority.
383  *
384  * @param delay when should this operation time out?
385  * @param rfd read file-descriptor
386  * @param task main function of the task
387  * @param task_cls closure of @a task
388  * @return unique task identifier for the job
389  *         only valid until @a task is started!
390  */
391 struct GNUNET_SCHEDULER_Task *
392 GNUNET_SCHEDULER_add_read_net (struct GNUNET_TIME_Relative delay,
393                                struct GNUNET_NETWORK_Handle *rfd,
394                                GNUNET_SCHEDULER_TaskCallback task,
395                                void *task_cls);
396
397
398 /**
399  * Schedule a new task to be run with a specified priority and to be
400  * run after the specified delay or when the specified file descriptor
401  * is ready for reading.  The delay can be used as a timeout on the
402  * socket being ready.  The task will be scheduled for execution once
403  * either the delay has expired or the socket operation is ready.  It
404  * will be run with the DEFAULT priority.
405  *
406  * @param delay when should this operation time out?
407  * @param priority priority to use for the task
408  * @param rfd read file-descriptor
409  * @param task main function of the task
410  * @param task_cls closure of @a task
411  * @return unique task identifier for the job
412  *         only valid until @a task is started!
413  */
414 struct GNUNET_SCHEDULER_Task *
415 GNUNET_SCHEDULER_add_read_net_with_priority (struct GNUNET_TIME_Relative delay,
416                                              enum GNUNET_SCHEDULER_Priority priority,
417                                              struct GNUNET_NETWORK_Handle *rfd,
418                                              GNUNET_SCHEDULER_TaskCallback task,
419                                              void *task_cls);
420
421
422 /**
423  * Schedule a new task to be run with a specified delay or when the
424  * specified file descriptor is ready for writing.  The delay can be
425  * used as a timeout on the socket being ready.  The task will be
426  * scheduled for execution once either the delay has expired or the
427  * socket operation is ready.  It will be run with the DEFAULT priority.
428  *
429  * * @param delay when should this operation time out?
430  * @param wfd write file-descriptor
431  * @param task main function of the task
432  * @param task_cls closure of @a task
433  * @return unique task identifier for the job
434  *         only valid until @a task is started!
435  */
436 struct GNUNET_SCHEDULER_Task *
437 GNUNET_SCHEDULER_add_write_net (struct GNUNET_TIME_Relative delay,
438                                 struct GNUNET_NETWORK_Handle *wfd,
439                                 GNUNET_SCHEDULER_TaskCallback task,
440                                 void *task_cls);
441
442
443 /**
444  * Schedule a new task to be run with a specified delay or when the
445  * specified file descriptor is ready.  The delay can be
446  * used as a timeout on the socket being ready.  The task will be
447  * scheduled for execution once either the delay has expired or the
448  * socket operation is ready.
449  *
450  * @param delay when should this operation time out?
451  * @param priority priority of the task
452  * @param fd file-descriptor
453  * @param on_read whether to poll the file-descriptor for readability
454  * @param on_write whether to poll the file-descriptor for writability
455  * @param task main function of the task
456  * @param task_cls closure of @a task
457  * @return unique task identifier for the job
458  *         only valid until "task" is started!
459  */
460 struct GNUNET_SCHEDULER_Task *
461 GNUNET_SCHEDULER_add_net_with_priority  (struct GNUNET_TIME_Relative delay,
462                                          enum GNUNET_SCHEDULER_Priority priority,
463                                          struct GNUNET_NETWORK_Handle *fd,
464                                          int on_read,
465                                          int on_write,
466                                          GNUNET_SCHEDULER_TaskCallback task,
467                                          void *task_cls);
468
469 /**
470  * Schedule a new task to be run with a specified delay or when the
471  * specified file descriptor is ready for reading.  The delay can be
472  * used as a timeout on the socket being ready.  The task will be
473  * scheduled for execution once either the delay has expired or the
474  * socket operation is ready. It will be run with the DEFAULT priority.
475  *
476  * * @param delay when should this operation time out?
477  * @param rfd read file-descriptor
478  * @param task main function of the task
479  * @param task_cls closure of @a task
480  * @return unique task identifier for the job
481  *         only valid until "task" is started!
482  */
483 struct GNUNET_SCHEDULER_Task *
484 GNUNET_SCHEDULER_add_read_file (struct GNUNET_TIME_Relative delay,
485                                 const struct GNUNET_DISK_FileHandle *rfd,
486                                 GNUNET_SCHEDULER_TaskCallback task,
487                                 void *task_cls);
488
489
490 /**
491  * Schedule a new task to be run with a specified delay or when the
492  * specified file descriptor is ready for writing.  The delay can be
493  * used as a timeout on the socket being ready.  The task will be
494  * scheduled for execution once either the delay has expired or the
495  * socket operation is ready. It will be run with the DEFAULT priority.
496  *
497  * * @param delay when should this operation time out?
498  * @param wfd write file-descriptor
499  * @param task main function of the task
500  * @param task_cls closure of @a task
501  * @return unique task identifier for the job
502  *         only valid until @a task is started!
503  */
504 struct GNUNET_SCHEDULER_Task *
505 GNUNET_SCHEDULER_add_write_file (struct GNUNET_TIME_Relative delay,
506                                  const struct GNUNET_DISK_FileHandle *wfd,
507                                  GNUNET_SCHEDULER_TaskCallback task,
508                                  void *task_cls);
509
510
511 /**
512  * Schedule a new task to be run with a specified delay or when the
513  * specified file descriptor is ready.  The delay can be
514  * used as a timeout on the socket being ready.  The task will be
515  * scheduled for execution once either the delay has expired or the
516  * socket operation is ready.
517  *
518  * @param delay when should this operation time out?
519  * @param priority priority of the task
520  * @param fd file-descriptor
521  * @param on_read whether to poll the file-descriptor for readability
522  * @param on_write whether to poll the file-descriptor for writability
523  * @param task main function of the task
524  * @param task_cls closure of @a task
525  * @return unique task identifier for the job
526  *         only valid until @a task is started!
527  */
528 struct GNUNET_SCHEDULER_Task *
529 GNUNET_SCHEDULER_add_file_with_priority (struct GNUNET_TIME_Relative delay,
530                                          enum GNUNET_SCHEDULER_Priority priority,
531                                          const struct GNUNET_DISK_FileHandle *fd,
532                                          int on_read, int on_write,
533                                          GNUNET_SCHEDULER_TaskCallback task,
534                                          void *task_cls);
535
536
537 /**
538  * Schedule a new task to be run with a specified delay or when any of
539  * the specified file descriptor sets is ready.  The delay can be used
540  * as a timeout on the socket(s) being ready.  The task will be
541  * scheduled for execution once either the delay has expired or any of
542  * the socket operations is ready.  This is the most general
543  * function of the "add" family.  Note that the "prerequisite_task"
544  * must be satisfied in addition to any of the other conditions.  In
545  * other words, the task will be started when
546  * <code>
547  * (prerequisite-run)
548  * && (delay-ready
549  *     || any-rs-ready
550  *     || any-ws-ready)
551  * </code>
552  *
553  * @param prio how important is this task?
554  * @param delay how long should we wait?
555  * @param rs set of file descriptors we want to read (can be NULL)
556  * @param ws set of file descriptors we want to write (can be NULL)
557  * @param task main function of the task
558  * @param task_cls closure of @a task
559  * @return unique task identifier for the job
560  *         only valid until "task" is started!
561  */
562 struct GNUNET_SCHEDULER_Task *
563 GNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio,
564                              struct GNUNET_TIME_Relative delay,
565                              const struct GNUNET_NETWORK_FDSet *rs,
566                              const struct GNUNET_NETWORK_FDSet *ws,
567                              GNUNET_SCHEDULER_TaskCallback task,
568                              void *task_cls);
569
570 /**
571  * Sets the select function to use in the scheduler (scheduler_select).
572  *
573  * @param new_select new select function to use (NULL to reset to default)
574  * @param new_select_cls closure for 'new_select'
575  */
576 void
577 GNUNET_SCHEDULER_set_select (GNUNET_SCHEDULER_select new_select,
578                              void *new_select_cls);
579
580
581 #if 0                           /* keep Emacsens' auto-indent happy */
582 {
583 #endif
584 #ifdef __cplusplus
585 }
586 #endif
587
588 #endif
589
590 /** @} */ /* end of group scheduler */