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