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 */