gnunet-android

GNUnet for Android
Log | Files | Refs | README

gnunet_scheduler_lib.h (32420B)


      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 it
      6       under the terms of the GNU Affero General Public License as published
      7       by the Free Software Foundation, either version 3 of the License,
      8       or (at your 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       Affero General Public License for more details.
     14 
     15       You should have received a copy of the GNU Affero General Public License
     16       along with this program.  If not, see <http://www.gnu.org/licenses/>.
     17 
     18      SPDX-License-Identifier: AGPL3.0-or-later
     19  */
     20 
     21 /**
     22  * @addtogroup libgnunetutil
     23  * Multi-function utilities library for GNUnet programs
     24  * @{
     25  *
     26  * @author Christian Grothoff
     27  *
     28  * @file
     29  * API to schedule computations using continuation passing style
     30  *
     31  * @defgroup scheduler  Scheduler library
     32  * Event loop (scheduler)
     33  *
     34  * Schedule computations using continuation passing style.
     35  *
     36  * @{
     37  */
     38 
     39 #ifndef GNUNET_SCHEDULER_LIB_H
     40 #define GNUNET_SCHEDULER_LIB_H
     41 
     42 #ifdef __cplusplus
     43 extern "C"
     44 {
     45 #if 0                           /* keep Emacsens' auto-indent happy */
     46 }
     47 #endif
     48 #endif
     49 
     50 /**
     51  * Opaque reference to a task.
     52  */
     53 struct GNUNET_SCHEDULER_Task;
     54 
     55 /**
     56  * Reasons why the schedule may have triggered
     57  * the task now.
     58  */
     59 enum GNUNET_SCHEDULER_Reason
     60 {
     61   /**
     62    * This task is not ready.
     63    */
     64   GNUNET_SCHEDULER_REASON_NONE = 0,
     65 
     66   /**
     67    * This is the very first task run during startup.
     68    */
     69   GNUNET_SCHEDULER_REASON_STARTUP = 1,
     70 
     71   /**
     72    * We are shutting down and are running all shutdown-related tasks.
     73    */
     74   GNUNET_SCHEDULER_REASON_SHUTDOWN = 2,
     75 
     76   /**
     77    * The specified timeout has expired.
     78    * (also set if the delay given was 0).
     79    */
     80   GNUNET_SCHEDULER_REASON_TIMEOUT = 4,
     81 
     82   /**
     83    * The reading socket is ready.
     84    */
     85   GNUNET_SCHEDULER_REASON_READ_READY = 8,
     86 
     87   /**
     88    * The writing socket is ready.
     89    */
     90   GNUNET_SCHEDULER_REASON_WRITE_READY = 16,
     91 
     92   /**
     93    * The prerequisite task is done.
     94    */
     95   GNUNET_SCHEDULER_REASON_PREREQ_DONE = 32
     96 };
     97 
     98 
     99 
    100 #include "gnunet_time_lib.h"
    101 #include "gnunet_network_lib.h"
    102 
    103 
    104 /**
    105  * Possible events on FDs, used as a bitmask.
    106  * Modelled after GPollFD.
    107  */
    108 enum GNUNET_SCHEDULER_EventType
    109 {
    110   /**
    111    * No event (useful for timeout).
    112    */
    113   GNUNET_SCHEDULER_ET_NONE = 0,
    114 
    115   /**
    116    * Data available for reading.
    117    */
    118   GNUNET_SCHEDULER_ET_IN = 1,
    119 
    120   /**
    121    * Buffer available for writing.
    122    */
    123   GNUNET_SCHEDULER_ET_OUT = 2,
    124 
    125   /**
    126    *
    127    */
    128   GNUNET_SCHEDULER_ET_HUP = 4,
    129 
    130   /**
    131    *
    132    */
    133   GNUNET_SCHEDULER_ET_ERR = 8,
    134 
    135   /**
    136    *
    137    */
    138   GNUNET_SCHEDULER_ET_PRI = 16,
    139 
    140   /**
    141    *
    142    */
    143   GNUNET_SCHEDULER_ET_NVAL = 32
    144 };
    145 
    146 
    147 /**
    148  * Information about an event relating to a file descriptor/socket.
    149  */
    150 struct GNUNET_SCHEDULER_FdInfo
    151 {
    152   /**
    153    * GNUnet network socket the event is about, matches @a sock,
    154    * NULL if this is about a file handle or if no network
    155    * handle was given to the scheduler originally.
    156    */
    157   const struct GNUNET_NETWORK_Handle *fd;
    158 
    159   /**
    160    * GNUnet file handle the event is about, matches @a sock,
    161    * NULL if this is about a network socket or if no network
    162    * handle was given to the scheduler originally.
    163    */
    164   const struct GNUNET_DISK_FileHandle *fh;
    165 
    166   /**
    167    * Type of the event that was generated related to @e sock.
    168    */
    169   enum GNUNET_SCHEDULER_EventType et;
    170 
    171   /**
    172    * Underlying OS handle the event was about.
    173    */
    174   int sock;
    175 };
    176 
    177 
    178 /**
    179  * Context information passed to each scheduler task.
    180  */
    181 struct GNUNET_SCHEDULER_TaskContext
    182 {
    183   /**
    184    * Reason why the task is run now
    185    */
    186   enum GNUNET_SCHEDULER_Reason reason;
    187 
    188   /**
    189    * Length of the following array.
    190    */
    191   unsigned int fds_len;
    192 
    193   /**
    194    * Array of length @e fds_len with information about ready FDs.
    195    * Note that we use the same format regardless of the internal
    196    * event loop that was used.  The given array should only contain
    197    * information about file descriptors relevant to the current task.
    198    */
    199   const struct GNUNET_SCHEDULER_FdInfo *fds;
    200 
    201   /**
    202    * Set of file descriptors ready for reading; note that additional
    203    * bits may be set that were not in the original request.
    204    * @deprecated
    205    */
    206   const struct GNUNET_NETWORK_FDSet *read_ready;
    207 
    208   /**
    209    * Set of file descriptors ready for writing; note that additional
    210    * bits may be set that were not in the original request.
    211    * @deprecated
    212    */
    213   const struct GNUNET_NETWORK_FDSet *write_ready;
    214 };
    215 
    216 
    217 /**
    218  * Function used by event-loop implementations to signal the scheduler
    219  * that a particular @a task is ready due to an event specified in the
    220  * et field of @a fdi.
    221  *
    222  * This function will then queue the task to notify the application
    223  * that the task is ready (with the respective priority).
    224  *
    225  * @param task the task that is ready
    226  * @param fdi information about the related FD
    227  */
    228 void
    229 GNUNET_SCHEDULER_task_ready (struct GNUNET_SCHEDULER_Task *task,
    230                              struct GNUNET_SCHEDULER_FdInfo *fdi);
    231 
    232 
    233 /**
    234  * Handle to the scheduler's state to be used by the driver.
    235  */
    236 struct GNUNET_SCHEDULER_Handle;
    237 
    238 
    239 /**
    240  * Function called by external event loop implementations to tell the
    241  * scheduler to run some of the tasks that are ready. Must be called
    242  * only after #GNUNET_SCHEDULER_driver_init has been called and before
    243  * #GNUNET_SCHEDULER_driver_done is called.
    244  * This function may return even though there are tasks left to run
    245  * just to give other tasks a chance as well.  If we return #GNUNET_YES,
    246  * the event loop implementation should call this function again as
    247  * soon as possible, while if we return #GNUNET_NO it must block until
    248  * either the operating system has more work (the scheduler has no more
    249  * work to do right now) or the timeout set by the scheduler (using the
    250  * set_wakeup callback) is reached.
    251  *
    252  * @param sh scheduler handle that was returned by
    253  *        #GNUNET_SCHEDULER_driver_init
    254  * @return #GNUNET_YES if there are more tasks that are ready,
    255  *         and thus we would like to run more (yield to avoid
    256  *         blocking other activities for too long) #GNUNET_NO
    257  *         if we are done running tasks (yield to block)
    258  */
    259 int
    260 GNUNET_SCHEDULER_do_work (struct GNUNET_SCHEDULER_Handle *sh);
    261 
    262 
    263 /**
    264  * API an external event loop has to implement for
    265  * #GNUNET_SCHEDULER_driver_init.
    266  */
    267 struct GNUNET_SCHEDULER_Driver
    268 {
    269   /**
    270    * Closure to pass to the functions in this struct.
    271    */
    272   void *cls;
    273 
    274   /**
    275    * Add a @a task to be run if the conditions specified in the
    276    * et field of the given @a fdi are satisfied. The et field will
    277    * be cleared after this call and the driver is expected to set
    278    * the type of the actual event before passing @a fdi to
    279    * #GNUNET_SCHEDULER_task_ready.
    280    *
    281    * @param cls closure
    282    * @param task task to add
    283    * @param fdi conditions to watch for
    284    * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
    285    *   (i.e. @a fdi too high or invalid)
    286    */
    287   int
    288   (*add)(void *cls,
    289          struct GNUNET_SCHEDULER_Task *task,
    290          struct GNUNET_SCHEDULER_FdInfo *fdi);
    291 
    292   /**
    293    * Delete a @a task from the set of tasks to be run. A task may
    294    * comprise multiple FdInfo entries previously added with the add
    295    * function. The driver is expected to delete them all.
    296    *
    297    * @param cls closure
    298    * @param task task to delete
    299    * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
    300    *   (i.e. @a task does not match prior @e add call)
    301    */
    302   int
    303   (*del)(void *cls,
    304          struct GNUNET_SCHEDULER_Task *task);
    305 
    306   /**
    307    * Set time at which we definitively want to get a wakeup call.
    308    *
    309    * @param cls closure
    310    * @param dt time when we want to wake up next
    311    */
    312   void
    313   (*set_wakeup)(void *cls,
    314                 struct GNUNET_TIME_Absolute dt);
    315 };
    316 
    317 
    318 /**
    319  * Signature of the main function of a task.
    320  *
    321  * @param cls closure
    322  */
    323 typedef void
    324 (*GNUNET_SCHEDULER_TaskCallback) (void *cls);
    325 
    326 
    327 /**
    328  * Function called by external event loop implementations to initialize
    329  * the scheduler. An external implementation has to provide @a driver
    330  * which contains callbacks for the scheduler (see definition of struct
    331  * #GNUNET_SCHEDULER_Driver). The callbacks are used to instruct the
    332  * external implementation to watch for events. If it detects any of
    333  * those events it is expected to call #GNUNET_SCHEDULER_do_work to let
    334  * the scheduler handle it. If an event is related to a specific task
    335  * (e.g. the scheduler gave instructions to watch a file descriptor),
    336  * the external implementation is expected to mark that task ready
    337  * before by calling #GNUNET_SCHEDULER_task_ready.
    338  *
    339  * This function has to be called before any tasks are scheduled and
    340  * before GNUNET_SCHEDULER_do_work is called for the first time. It
    341  * allocates resources that have to be freed again by calling
    342  * #GNUNET_SCHEDULER_driver_done.
    343  *
    344  * This function installs the same signal handlers as
    345  * #GNUNET_SCHEDULER_run. This means SIGTERM (and other similar signals)
    346  * will induce a call to #GNUNET_SCHEDULER_shutdown during the next
    347  * call to #GNUNET_SCHEDULER_do_work. As a result, SIGTERM causes all
    348  * active tasks to be scheduled with reason
    349  * #GNUNET_SCHEDULER_REASON_SHUTDOWN. (However, tasks added afterwards
    350  * will execute normally!). Note that any particular signal will only
    351  * shut down one scheduler; applications should always only create a
    352  * single scheduler.
    353  *
    354  * @param driver to use for the event loop
    355  * @return handle to be passed to #GNUNET_SCHEDULER_do_work and
    356  *         #GNUNET_SCHEDULER_driver_done
    357  */
    358 struct GNUNET_SCHEDULER_Handle *
    359 GNUNET_SCHEDULER_driver_init (const struct GNUNET_SCHEDULER_Driver *driver);
    360 
    361 
    362 /**
    363  * Counter-part of #GNUNET_SCHEDULER_driver_init. Has to be called
    364  * by external event loop implementations after the scheduler has
    365  * shut down. This is the case if both of the following conditions
    366  * are met:
    367  *
    368  * - all tasks the scheduler has added through the driver's add
    369  *   callback have been removed again through the driver's del
    370  *   callback
    371  * - the timeout the scheduler has set through the driver's
    372  *   add_wakeup callback is FOREVER
    373  *
    374  * @param sh the handle returned by #GNUNET_SCHEDULER_driver_init
    375  */
    376 void
    377 GNUNET_SCHEDULER_driver_done (struct GNUNET_SCHEDULER_Handle *sh);
    378 
    379 
    380 /**
    381  * Obtain the driver for using select() as the event loop.
    382  *
    383  * @return NULL on error
    384  */
    385 struct GNUNET_SCHEDULER_Driver *
    386 GNUNET_SCHEDULER_driver_select (void);
    387 
    388 
    389 /**
    390  * Signature of the select function used by the scheduler.
    391  * #GNUNET_NETWORK_socket_select matches it.
    392  *
    393  * @param cls closure
    394  * @param rfds set of sockets to be checked for readability
    395  * @param wfds set of sockets to be checked for writability
    396  * @param efds set of sockets to be checked for exceptions
    397  * @param timeout relative value when to return
    398  * @return number of selected sockets, #GNUNET_SYSERR on error
    399  */
    400 typedef int
    401 (*GNUNET_SCHEDULER_select) (void *cls,
    402                             struct GNUNET_NETWORK_FDSet *rfds,
    403                             struct GNUNET_NETWORK_FDSet *wfds,
    404                             struct GNUNET_NETWORK_FDSet *efds,
    405                             struct GNUNET_TIME_Relative timeout);
    406 
    407 
    408 /**
    409  * Initialize and run scheduler.  This function will return when all
    410  * tasks have completed.  On systems with signals, receiving a SIGTERM
    411  * (and other similar signals) will cause #GNUNET_SCHEDULER_shutdown
    412  * to be run after the active task is complete.  As a result, SIGTERM
    413  * causes all shutdown tasks to be scheduled with reason
    414  * #GNUNET_SCHEDULER_REASON_SHUTDOWN.  (However, tasks added
    415  * afterwards will execute normally!).  Note that any particular
    416  * signal will only shut down one scheduler; applications should
    417  * always only create a single scheduler.
    418  *
    419  * @param task task to run first (and immediately)
    420  * @param task_cls closure of @a task
    421  */
    422 void
    423 GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_TaskCallback task,
    424                       void *task_cls);
    425 
    426 /**
    427  * Initialize and run scheduler.  This function will return when all
    428  * tasks have completed.  When @ install_signals is GNUNET_YES, then
    429  * this function behaves in the same was as GNUNET_SCHEDULER_run does.
    430  * If @ install_signals is GNUNET_NO then no signal handlers are
    431  * installed.
    432  *
    433  * @param install_signals whether to install signals (GNUNET_YES/NO)
    434  * @param task task to run first (and immediately)
    435  * @param task_cls closure of @a task
    436  */
    437 void
    438 GNUNET_SCHEDULER_run_with_optional_signals (int install_signals,
    439                                             GNUNET_SCHEDULER_TaskCallback task,
    440                                             void *task_cls);
    441 
    442 
    443 /**
    444  * Request the shutdown of a scheduler.  Marks all tasks
    445  * awaiting shutdown as ready. Note that tasks
    446  * scheduled with #GNUNET_SCHEDULER_add_shutdown() AFTER this call
    447  * will be delayed until the next shutdown signal.
    448  */
    449 void
    450 GNUNET_SCHEDULER_shutdown (void);
    451 
    452 
    453 /**
    454  * Get information about the current load of this scheduler.  Use this
    455  * function to determine if an elective task should be added or simply
    456  * dropped (if the decision should be made based on the number of
    457  * tasks ready to run).
    458  *
    459  * @param p priority-level to query, use KEEP to query the level
    460  *          of the current task, use COUNT to get the sum over
    461  *          all priority levels
    462  * @return number of tasks pending right now
    463  */
    464 unsigned int
    465 GNUNET_SCHEDULER_get_load (enum GNUNET_SCHEDULER_Priority p);
    466 
    467 
    468 /**
    469  * Obtain the reasoning why the current task was
    470  * started.
    471  *
    472  * @return task context with information why the current task is run
    473  */
    474 const struct GNUNET_SCHEDULER_TaskContext *
    475 GNUNET_SCHEDULER_get_task_context (void);
    476 
    477 
    478 /**
    479  * Cancel the task with the specified identifier.
    480  * The task must not yet have run. Only allowed to be called as long as the
    481  * scheduler is running, that is one of the following conditions is met:
    482  *
    483  * - #GNUNET_SCHEDULER_run has been called and has not returned yet
    484  * - #GNUNET_SCHEDULER_driver_init has been run and
    485  *   #GNUNET_SCHEDULER_driver_done has not been called yet
    486  *
    487  * @param task id of the task to cancel
    488  * @return original closure of the task
    489  */
    490 void *
    491 GNUNET_SCHEDULER_cancel (struct GNUNET_SCHEDULER_Task *task);
    492 
    493 
    494 /**
    495  * Continue the current execution with the given function.  This is
    496  * similar to the other "add" functions except that there is no delay
    497  * and the reason code can be specified.
    498  *
    499  * @param task main function of the task
    500  * @param task_cls closure for @a task
    501  * @param reason reason for task invocation
    502  * @param priority priority to use for the task
    503  */
    504 void
    505 GNUNET_SCHEDULER_add_with_reason_and_priority (
    506   GNUNET_SCHEDULER_TaskCallback task,
    507   void *task_cls,
    508   enum GNUNET_SCHEDULER_Reason reason,
    509   enum GNUNET_SCHEDULER_Priority priority);
    510 
    511 
    512 /**
    513  * Schedule a new task to be run with a specified priority.
    514  *
    515  * @param prio how important is the new task?
    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 @a task is started!
    520  */
    521 struct GNUNET_SCHEDULER_Task *
    522 GNUNET_SCHEDULER_add_with_priority (enum GNUNET_SCHEDULER_Priority prio,
    523                                     GNUNET_SCHEDULER_TaskCallback task,
    524                                     void *task_cls);
    525 
    526 
    527 /**
    528  * Schedule a new task to be run as soon as possible. Note that this
    529  * does not guarantee that this will be the next task that is being
    530  * run, as other tasks with higher priority (or that are already ready
    531  * to run) might get to run first.  Just as with delays, clients must
    532  * not rely on any particular order of execution between tasks
    533  * scheduled concurrently.
    534  *
    535  * The task will be run with the DEFAULT priority.
    536  *
    537  * @param task main function of the task
    538  * @param task_cls closure of @a task
    539  * @return unique task identifier for the job
    540  *         only valid until @a task is started!
    541  */
    542 struct GNUNET_SCHEDULER_Task *
    543 GNUNET_SCHEDULER_add_now (GNUNET_SCHEDULER_TaskCallback task,
    544                           void *task_cls);
    545 
    546 
    547 /**
    548  * Schedule a new task to be run on shutdown, that is when a CTRL-C
    549  * signal is received, or when #GNUNET_SCHEDULER_shutdown() is being
    550  * invoked.
    551  *
    552  * @param task main function of the task
    553  * @param task_cls closure of @a task
    554  * @return unique task identifier for the job
    555  *         only valid until @a task is started!
    556  */
    557 struct GNUNET_SCHEDULER_Task *
    558 GNUNET_SCHEDULER_add_shutdown (GNUNET_SCHEDULER_TaskCallback task,
    559                                void *task_cls);
    560 
    561 
    562 /**
    563  * Schedule a new task to be run as soon as possible with the
    564  * (transitive) ignore-shutdown flag either explicitly set or
    565  * explicitly enabled.  This task (and all tasks created from it,
    566  * other than by another call to this function) will either count or
    567  * not count for the 'lifeness' of the process.  This API is only
    568  * useful in a few special cases.
    569  *
    570  * @param lifeness #GNUNET_YES if the task counts for lifeness, #GNUNET_NO if not.
    571  * @param task main function of the task
    572  * @param task_cls closure of @a task
    573  * @return unique task identifier for the job
    574  *         only valid until @a task is started!
    575  */
    576 struct GNUNET_SCHEDULER_Task *
    577 GNUNET_SCHEDULER_add_now_with_lifeness (int lifeness,
    578                                         GNUNET_SCHEDULER_TaskCallback task,
    579                                         void *task_cls);
    580 
    581 
    582 /**
    583  * Schedule a new task to be run with a specified delay.  The task
    584  * will be scheduled for execution once the delay has expired. It
    585  * will be run with the DEFAULT priority.
    586  *
    587  * @param delay with which the operation should be run
    588  * @param task main function of the task
    589  * @param task_cls closure of @a task
    590  * @return unique task identifier for the job
    591  *         only valid until @a task is started!
    592  */
    593 struct GNUNET_SCHEDULER_Task *
    594 GNUNET_SCHEDULER_add_delayed (struct GNUNET_TIME_Relative delay,
    595                               GNUNET_SCHEDULER_TaskCallback task,
    596                               void *task_cls);
    597 
    598 
    599 /**
    600  * Schedule a new task to be run at the specified time.  The task
    601  * will be scheduled for execution once specified time has been
    602  * reached. It will be run with the DEFAULT priority.
    603  *
    604  * @param at time at which this operation should run
    605  * @param task main function of the task
    606  * @param task_cls closure of @a task
    607  * @return unique task identifier for the job
    608  *         only valid until @a task is started!
    609  */
    610 struct GNUNET_SCHEDULER_Task *
    611 GNUNET_SCHEDULER_add_at (struct GNUNET_TIME_Absolute at,
    612                          GNUNET_SCHEDULER_TaskCallback task,
    613                          void *task_cls);
    614 
    615 
    616 /**
    617  * Schedule a new task to be run with a specified delay.  The task
    618  * will be scheduled for execution once the delay has expired.
    619  *
    620  * @param delay when should this operation time out?
    621  * @param priority priority to use for the task
    622  * @param task main function of the task
    623  * @param task_cls closure of @a task
    624  * @return unique task identifier for the job
    625  *         only valid until @a task is started!
    626  */
    627 struct GNUNET_SCHEDULER_Task *
    628 GNUNET_SCHEDULER_add_delayed_with_priority (struct GNUNET_TIME_Relative delay,
    629                                             enum GNUNET_SCHEDULER_Priority
    630                                             priority,
    631                                             GNUNET_SCHEDULER_TaskCallback task,
    632                                             void *task_cls);
    633 
    634 
    635 /**
    636  * Schedule a new task to be run at the specified time.  The task
    637  * will be scheduled for execution at time @a at.
    638  *
    639  * @param at time when the operation should run
    640  * @param priority priority to use for the task
    641  * @param task main function of the task
    642  * @param task_cls closure of @a task
    643  * @return unique task identifier for the job
    644  *         only valid until @a task is started!
    645  */
    646 struct GNUNET_SCHEDULER_Task *
    647 GNUNET_SCHEDULER_add_at_with_priority (struct GNUNET_TIME_Absolute at,
    648                                        enum GNUNET_SCHEDULER_Priority priority,
    649                                        GNUNET_SCHEDULER_TaskCallback task,
    650                                        void *task_cls);
    651 
    652 
    653 /**
    654  * Schedule a new task to be run with a specified delay or when the
    655  * specified file descriptor is ready for reading.  The delay can be
    656  * used as a timeout on the socket being ready.  The task will be
    657  * scheduled for execution once either the delay has expired or the
    658  * socket operation is ready.  It will be run with the DEFAULT priority.
    659  * Only allowed to be called as long as the scheduler is running, that
    660  * is one of the following conditions is met:
    661  *
    662  * - #GNUNET_SCHEDULER_run has been called and has not returned yet
    663  * - #GNUNET_SCHEDULER_driver_init has been run and
    664  *   #GNUNET_SCHEDULER_driver_done has not been called yet
    665  *
    666  * @param delay when should this operation time out?
    667  * @param rfd read file-descriptor
    668  * @param task main function of the task
    669  * @param task_cls closure of @a task
    670  * @return unique task identifier for the job
    671  *         only valid until @a task is started!
    672  */
    673 struct GNUNET_SCHEDULER_Task *
    674 GNUNET_SCHEDULER_add_read_net (struct GNUNET_TIME_Relative delay,
    675                                struct GNUNET_NETWORK_Handle *rfd,
    676                                GNUNET_SCHEDULER_TaskCallback task,
    677                                void *task_cls);
    678 
    679 
    680 /**
    681  * Schedule a new task to be run with a specified priority and to be
    682  * run after the specified delay or when the specified file descriptor
    683  * is ready for reading.  The delay can be used as a timeout on the
    684  * socket being ready.  The task will be scheduled for execution once
    685  * either the delay has expired or the socket operation is ready.  It
    686  * will be run with the DEFAULT priority.
    687  * Only allowed to be called as long as the scheduler is running, that
    688  * is one of the following conditions is met:
    689  *
    690  * - #GNUNET_SCHEDULER_run has been called and has not returned yet
    691  * - #GNUNET_SCHEDULER_driver_init has been run and
    692  *   #GNUNET_SCHEDULER_driver_done has not been called yet
    693  *
    694  * @param delay when should this operation time out?
    695  * @param priority priority to use for the task
    696  * @param rfd read file-descriptor
    697  * @param task main function of the task
    698  * @param task_cls closure of @a task
    699  * @return unique task identifier for the job
    700  *         only valid until @a task is started!
    701  */
    702 struct GNUNET_SCHEDULER_Task *
    703 GNUNET_SCHEDULER_add_read_net_with_priority (struct GNUNET_TIME_Relative delay,
    704                                              enum GNUNET_SCHEDULER_Priority
    705                                              priority,
    706                                              struct GNUNET_NETWORK_Handle *rfd,
    707                                              GNUNET_SCHEDULER_TaskCallback task,
    708                                              void *task_cls);
    709 
    710 
    711 /**
    712  * Schedule a new task to be run with a specified delay or when the
    713  * specified file descriptor is ready for writing.  The delay can be
    714  * used as a timeout on the socket being ready.  The task will be
    715  * scheduled for execution once either the delay has expired or the
    716  * socket operation is ready.  It will be run with the priority of
    717  * the calling task.
    718  * Only allowed to be called as long as the scheduler is running, that
    719  * is one of the following conditions is met:
    720  *
    721  * - #GNUNET_SCHEDULER_run has been called and has not returned yet
    722  * - #GNUNET_SCHEDULER_driver_init has been run and
    723  *   #GNUNET_SCHEDULER_driver_done has not been called yet
    724  *
    725  * @param delay when should this operation time out?
    726  * @param wfd write file-descriptor
    727  * @param task main function of the task
    728  * @param task_cls closure of @a task
    729  * @return unique task identifier for the job
    730  *         only valid until @a task is started!
    731  */
    732 struct GNUNET_SCHEDULER_Task *
    733 GNUNET_SCHEDULER_add_write_net (struct GNUNET_TIME_Relative delay,
    734                                 struct GNUNET_NETWORK_Handle *wfd,
    735                                 GNUNET_SCHEDULER_TaskCallback task,
    736                                 void *task_cls);
    737 
    738 
    739 /**
    740  * Schedule a new task to be run with a specified delay or when the
    741  * specified file descriptor is ready.  The delay can be
    742  * used as a timeout on the socket being ready.  The task will be
    743  * scheduled for execution once either the delay has expired or the
    744  * socket operation is ready.
    745  * Only allowed to be called as long as the scheduler is running, that
    746  * is one of the following conditions is met:
    747  *
    748  * - #GNUNET_SCHEDULER_run has been called and has not returned yet
    749  * - #GNUNET_SCHEDULER_driver_init has been run and
    750  *   #GNUNET_SCHEDULER_driver_done has not been called yet
    751  *
    752  * @param delay when should this operation time out?
    753  * @param priority priority of the task
    754  * @param fd file-descriptor
    755  * @param on_read whether to poll the file-descriptor for readability
    756  * @param on_write whether to poll the file-descriptor for writability
    757  * @param task main function of the task
    758  * @param task_cls closure of task
    759  * @return unique task identifier for the job
    760  *         only valid until "task" is started!
    761  */
    762 struct GNUNET_SCHEDULER_Task *
    763 GNUNET_SCHEDULER_add_net_with_priority (struct GNUNET_TIME_Relative delay,
    764                                         enum GNUNET_SCHEDULER_Priority priority,
    765                                         struct GNUNET_NETWORK_Handle *fd,
    766                                         int on_read,
    767                                         int on_write,
    768                                         GNUNET_SCHEDULER_TaskCallback task,
    769                                         void *task_cls);
    770 
    771 
    772 /**
    773  * Schedule a new task to be run with a specified delay or when the
    774  * specified file descriptor is ready for reading.  The delay can be
    775  * used as a timeout on the socket being ready.  The task will be
    776  * scheduled for execution once either the delay has expired or the
    777  * socket operation is ready. It will be run with the DEFAULT priority.
    778  * Only allowed to be called as long as the scheduler is running, that
    779  * is one of the following conditions is met:
    780  *
    781  * - #GNUNET_SCHEDULER_run has been called and has not returned yet
    782  * - #GNUNET_SCHEDULER_driver_init has been run and
    783  *   #GNUNET_SCHEDULER_driver_done has not been called yet
    784  *
    785  * @param delay when should this operation time out?
    786  * @param rfd read file-descriptor
    787  * @param task main function of the task
    788  * @param task_cls closure of @a task
    789  * @return unique task identifier for the job
    790  *         only valid until @a task is started!
    791  */
    792 struct GNUNET_SCHEDULER_Task *
    793 GNUNET_SCHEDULER_add_read_file (struct GNUNET_TIME_Relative delay,
    794                                 const struct GNUNET_DISK_FileHandle *rfd,
    795                                 GNUNET_SCHEDULER_TaskCallback task,
    796                                 void *task_cls);
    797 
    798 
    799 /**
    800  * Schedule a new task to be run with a specified delay or when the
    801  * specified file descriptor is ready for writing.  The delay can be
    802  * used as a timeout on the socket being ready.  The task will be
    803  * scheduled for execution once either the delay has expired or the
    804  * socket operation is ready. It will be run with the DEFAULT priority.
    805  * Only allowed to be called as long as the scheduler is running, that
    806  * is one of the following conditions is met:
    807  *
    808  * - #GNUNET_SCHEDULER_run has been called and has not returned yet
    809  * - #GNUNET_SCHEDULER_driver_init has been run and
    810  *   #GNUNET_SCHEDULER_driver_done has not been called yet
    811  *
    812  * @param delay when should this operation time out?
    813  * @param wfd write file-descriptor
    814  * @param task main function of the task
    815  * @param task_cls closure of @a task
    816  * @return unique task identifier for the job
    817  *         only valid until @a task is started!
    818  */
    819 struct GNUNET_SCHEDULER_Task *
    820 GNUNET_SCHEDULER_add_write_file (struct GNUNET_TIME_Relative delay,
    821                                  const struct GNUNET_DISK_FileHandle *wfd,
    822                                  GNUNET_SCHEDULER_TaskCallback task,
    823                                  void *task_cls);
    824 
    825 
    826 /**
    827  * Schedule a new task to be run with a specified delay or when the
    828  * specified file descriptor is ready.  The delay can be
    829  * used as a timeout on the socket being ready.  The task will be
    830  * scheduled for execution once either the delay has expired or the
    831  * socket operation is ready.
    832  * Only allowed to be called as long as the scheduler is running, that
    833  * is one of the following conditions is met:
    834  *
    835  * - #GNUNET_SCHEDULER_run has been called and has not returned yet
    836  * - #GNUNET_SCHEDULER_driver_init has been run and
    837  *   #GNUNET_SCHEDULER_driver_done has not been called yet
    838  *
    839  * @param delay when should this operation time out?
    840  * @param priority priority of the task
    841  * @param fd file-descriptor
    842  * @param on_read whether to poll the file-descriptor for readability
    843  * @param on_write whether to poll the file-descriptor for writability
    844  * @param task main function of the task
    845  * @param task_cls closure of @a task
    846  * @return unique task identifier for the job
    847  *         only valid until @a task is started!
    848  */
    849 struct GNUNET_SCHEDULER_Task *
    850 GNUNET_SCHEDULER_add_file_with_priority (struct GNUNET_TIME_Relative delay,
    851                                          enum GNUNET_SCHEDULER_Priority
    852                                          priority,
    853                                          const struct
    854                                          GNUNET_DISK_FileHandle *fd,
    855                                          int on_read,
    856                                          int on_write,
    857                                          GNUNET_SCHEDULER_TaskCallback task,
    858                                          void *task_cls);
    859 
    860 
    861 /**
    862  * Schedule a new task to be run with a specified delay or when any of
    863  * the specified file descriptor sets is ready.  The delay can be used
    864  * as a timeout on the socket(s) being ready.  The task will be
    865  * scheduled for execution once either the delay has expired or any of
    866  * the socket operations is ready.  This is the most general
    867  * function of the "add" family.  Note that the "prerequisite_task"
    868  * must be satisfied in addition to any of the other conditions.  In
    869  * other words, the task will be started when
    870  * <code>
    871  * (prerequisite-run)
    872  * && (delay-ready
    873  *     || any-rs-ready
    874  *     || any-ws-ready) )
    875  * </code>
    876  * Only allowed to be called as long as the scheduler is running, that
    877  * is one of the following conditions is met:
    878  *
    879  * - #GNUNET_SCHEDULER_run has been called and has not returned yet
    880  * - #GNUNET_SCHEDULER_driver_init has been run and
    881  *   #GNUNET_SCHEDULER_driver_done has not been called yet
    882  *
    883  * @param prio how important is this task?
    884  * @param delay how long should we wait?
    885  * @param rs set of file descriptors we want to read (can be NULL)
    886  * @param ws set of file descriptors we want to write (can be NULL)
    887  * @param task main function of the task
    888  * @param task_cls closure of @a task
    889  * @return unique task identifier for the job
    890  *         only valid until @a task is started!
    891  */
    892 struct GNUNET_SCHEDULER_Task *
    893 GNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio,
    894                              struct GNUNET_TIME_Relative delay,
    895                              const struct GNUNET_NETWORK_FDSet *rs,
    896                              const struct GNUNET_NETWORK_FDSet *ws,
    897                              GNUNET_SCHEDULER_TaskCallback task,
    898                              void *task_cls);
    899 
    900 /**
    901  * Sets the select function to use in the scheduler (scheduler_select).
    902  *
    903  * @param new_select new select function to use (NULL to reset to default)
    904  * @param new_select_cls closure for @a new_select
    905  */
    906 void
    907 GNUNET_SCHEDULER_set_select (GNUNET_SCHEDULER_select new_select,
    908                              void *new_select_cls);
    909 
    910 
    911 /**
    912  * Change the async scope for the currently executing task and (transitively)
    913  * for all tasks scheduled by the current task after calling this function.
    914  * Nested tasks can begin their own nested async scope.
    915  *
    916  * Once the current task is finished, the async scope ID is reset to
    917  * its previous value.
    918  *
    919  * Must only be called from a running task.
    920  *
    921  * @param aid the asynchronous scope id to enter
    922  */
    923 void
    924 GNUNET_SCHEDULER_begin_async_scope (struct GNUNET_AsyncScopeId *aid);
    925 
    926 
    927 #if 0                           /* keep Emacsens' auto-indent happy */
    928 {
    929 #endif
    930 #ifdef __cplusplus
    931 }
    932 #endif
    933 
    934 #endif
    935 
    936 /** @} */ /* end of group scheduler */
    937 
    938 /** @} */ /* end of group addition */