diff options
Diffstat (limited to 'src/util/scheduler.c')
-rw-r--r-- | src/util/scheduler.c | 555 |
1 files changed, 262 insertions, 293 deletions
diff --git a/src/util/scheduler.c b/src/util/scheduler.c index 2bb356eb6..16f65b457 100644 --- a/src/util/scheduler.c +++ b/src/util/scheduler.c | |||
@@ -95,11 +95,6 @@ struct Task | |||
95 | */ | 95 | */ |
96 | enum GNUNET_SCHEDULER_Priority priority; | 96 | enum GNUNET_SCHEDULER_Priority priority; |
97 | 97 | ||
98 | /** | ||
99 | * Should this task be run on shutdown? | ||
100 | */ | ||
101 | int run_on_shutdown; | ||
102 | |||
103 | }; | 98 | }; |
104 | 99 | ||
105 | 100 | ||
@@ -135,12 +130,6 @@ struct GNUNET_SCHEDULER_Handle | |||
135 | GNUNET_SCHEDULER_TaskIdentifier lowest_pending_id; | 130 | GNUNET_SCHEDULER_TaskIdentifier lowest_pending_id; |
136 | 131 | ||
137 | /** | 132 | /** |
138 | * GNUNET_NO if we are running normally, | ||
139 | * GNUNET_YES if we are in shutdown mode. | ||
140 | */ | ||
141 | int shutdown; | ||
142 | |||
143 | /** | ||
144 | * Number of tasks on the ready list. | 133 | * Number of tasks on the ready list. |
145 | */ | 134 | */ |
146 | unsigned int ready_count; | 135 | unsigned int ready_count; |
@@ -260,6 +249,8 @@ update_sets (struct GNUNET_SCHEDULER_Handle *sched, | |||
260 | GNUNET_NETWORK_fdset_add (rs, pos->read_set); | 249 | GNUNET_NETWORK_fdset_add (rs, pos->read_set); |
261 | if (pos->write_set != NULL) | 250 | if (pos->write_set != NULL) |
262 | GNUNET_NETWORK_fdset_add (ws, pos->write_set); | 251 | GNUNET_NETWORK_fdset_add (ws, pos->write_set); |
252 | if (pos->reason != 0) | ||
253 | *timeout = GNUNET_TIME_UNIT_ZERO; | ||
263 | pos = pos->next; | 254 | pos = pos->next; |
264 | } | 255 | } |
265 | } | 256 | } |
@@ -309,12 +300,7 @@ is_ready (struct GNUNET_SCHEDULER_Handle *sched, | |||
309 | const struct GNUNET_NETWORK_FDSet *rs, | 300 | const struct GNUNET_NETWORK_FDSet *rs, |
310 | const struct GNUNET_NETWORK_FDSet *ws) | 301 | const struct GNUNET_NETWORK_FDSet *ws) |
311 | { | 302 | { |
312 | if ((GNUNET_NO == task->run_on_shutdown) && (GNUNET_YES == sched->shutdown)) | 303 | if (now.value >= task->timeout.value) |
313 | return GNUNET_NO; | ||
314 | if ((GNUNET_YES == task->run_on_shutdown) && | ||
315 | (GNUNET_YES == sched->shutdown)) | ||
316 | task->reason |= GNUNET_SCHEDULER_REASON_SHUTDOWN; | ||
317 | if (now.value >= task->timeout.value) | ||
318 | task->reason |= GNUNET_SCHEDULER_REASON_TIMEOUT; | 304 | task->reason |= GNUNET_SCHEDULER_REASON_TIMEOUT; |
319 | if ((0 == (task->reason & GNUNET_SCHEDULER_REASON_READ_READY)) && | 305 | if ((0 == (task->reason & GNUNET_SCHEDULER_REASON_READ_READY)) && |
320 | (rs != NULL) && (set_overlaps (rs, task->read_set))) | 306 | (rs != NULL) && (set_overlaps (rs, task->read_set))) |
@@ -395,6 +381,32 @@ check_ready (struct GNUNET_SCHEDULER_Handle *handle, | |||
395 | 381 | ||
396 | 382 | ||
397 | /** | 383 | /** |
384 | * Request the shutdown of a scheduler. Marks all currently | ||
385 | * pending tasks as ready because of shutdown. This will | ||
386 | * cause all tasks to run (as soon as possible, respecting | ||
387 | * priorities and prerequisite tasks). Note that tasks | ||
388 | * scheduled AFTER this call may still be delayed arbitrarily. | ||
389 | * | ||
390 | * @param sched the scheduler | ||
391 | */ | ||
392 | void | ||
393 | GNUNET_SCHEDULER_shutdown (struct GNUNET_SCHEDULER_Handle *sched) | ||
394 | { | ||
395 | struct Task *pos; | ||
396 | |||
397 | pos = sched->pending; | ||
398 | while (pos != NULL) | ||
399 | { | ||
400 | pos->reason |= GNUNET_SCHEDULER_REASON_SHUTDOWN; | ||
401 | /* we don't move the task into the ready queue yet; check_ready | ||
402 | will do that later, possibly adding additional | ||
403 | readyness-factors */ | ||
404 | pos = pos->next; | ||
405 | } | ||
406 | } | ||
407 | |||
408 | |||
409 | /** | ||
398 | * Destroy a task (release associated resources) | 410 | * Destroy a task (release associated resources) |
399 | * | 411 | * |
400 | * @param t task to destroy | 412 | * @param t task to destroy |
@@ -415,7 +427,7 @@ destroy_task (struct Task *t) | |||
415 | * empty. Keep running tasks until we are either no longer running | 427 | * empty. Keep running tasks until we are either no longer running |
416 | * "URGENT" tasks or until we have at least one "pending" task (which | 428 | * "URGENT" tasks or until we have at least one "pending" task (which |
417 | * may become ready, hence we should select on it). Naturally, if | 429 | * may become ready, hence we should select on it). Naturally, if |
418 | * there are no more ready tasks, we also return. | 430 | * there are no more ready tasks, we also return. |
419 | * | 431 | * |
420 | * @param sched the scheduler | 432 | * @param sched the scheduler |
421 | */ | 433 | */ |
@@ -459,7 +471,7 @@ run_ready (struct GNUNET_SCHEDULER_Handle *sched) | |||
459 | while ((sched->pending == NULL) || (p == GNUNET_SCHEDULER_PRIORITY_URGENT)); | 471 | while ((sched->pending == NULL) || (p == GNUNET_SCHEDULER_PRIORITY_URGENT)); |
460 | } | 472 | } |
461 | 473 | ||
462 | 474 | #ifndef MINGW | |
463 | /** | 475 | /** |
464 | * Pipe used to communicate shutdown via signal. | 476 | * Pipe used to communicate shutdown via signal. |
465 | */ | 477 | */ |
@@ -478,19 +490,25 @@ sighandler_shutdown () | |||
478 | (sigpipe, GNUNET_DISK_PIPE_END_WRITE), &c, | 490 | (sigpipe, GNUNET_DISK_PIPE_END_WRITE), &c, |
479 | sizeof (c)); | 491 | sizeof (c)); |
480 | } | 492 | } |
493 | #endif | ||
481 | 494 | ||
482 | 495 | ||
483 | /** | 496 | /** |
484 | * Initialize a scheduler using this thread. This function will | 497 | * Initialize and run scheduler. This function will return when all |
485 | * return when either a shutdown was initiated (via signal) and all | 498 | * tasks have completed. On systems with signals, receiving a SIGTERM |
486 | * tasks marked to "run_on_shutdown" have been completed or when all | 499 | * (and other similar signals) will cause "GNUNET_SCHEDULER_shutdown" |
487 | * tasks in general have been completed. | 500 | * to be run after the active task is complete. As a result, SIGTERM |
501 | * causes all active tasks to be scheduled with reason | ||
502 | * "GNUNET_SCHEDULER_REASON_SHUTDOWN". (However, tasks added | ||
503 | * afterwards will execute normally!). Note that any particular signal | ||
504 | * will only shut down one scheduler; applications should always only | ||
505 | * create a single scheduler. | ||
488 | * | 506 | * |
489 | * @param task task to run immediately | 507 | * @param task task to run immediately |
490 | * @param cls closure of task | 508 | * @param task_cls closure of task |
491 | */ | 509 | */ |
492 | void | 510 | void |
493 | GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_Task task, void *cls) | 511 | GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_Task task, void *task_cls) |
494 | { | 512 | { |
495 | struct GNUNET_SCHEDULER_Handle sched; | 513 | struct GNUNET_SCHEDULER_Handle sched; |
496 | struct GNUNET_NETWORK_FDSet *rs; | 514 | struct GNUNET_NETWORK_FDSet *rs; |
@@ -501,12 +519,12 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_Task task, void *cls) | |||
501 | struct GNUNET_SIGNAL_Context *shc_term; | 519 | struct GNUNET_SIGNAL_Context *shc_term; |
502 | struct GNUNET_SIGNAL_Context *shc_quit; | 520 | struct GNUNET_SIGNAL_Context *shc_quit; |
503 | struct GNUNET_SIGNAL_Context *shc_hup; | 521 | struct GNUNET_SIGNAL_Context *shc_hup; |
504 | struct Task *tpos; | ||
505 | unsigned long long last_tr; | 522 | unsigned long long last_tr; |
506 | unsigned int busy_wait_warning; | 523 | unsigned int busy_wait_warning; |
507 | #ifndef MINGW | 524 | #ifndef MINGW |
508 | const struct GNUNET_DISK_FileHandle *pr; | 525 | const struct GNUNET_DISK_FileHandle *pr; |
509 | #endif | 526 | #endif |
527 | char c; | ||
510 | 528 | ||
511 | rs = GNUNET_NETWORK_fdset_create (); | 529 | rs = GNUNET_NETWORK_fdset_create (); |
512 | ws = GNUNET_NETWORK_fdset_create (); | 530 | ws = GNUNET_NETWORK_fdset_create (); |
@@ -516,38 +534,40 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_Task task, void *cls) | |||
516 | GNUNET_assert (sigpipe != NULL); | 534 | GNUNET_assert (sigpipe != NULL); |
517 | pr = GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ); | 535 | pr = GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ); |
518 | GNUNET_assert (pr != NULL); | 536 | GNUNET_assert (pr != NULL); |
519 | shc_int = GNUNET_SIGNAL_handler_install (SIGINT, &sighandler_shutdown); | 537 | shc_int = GNUNET_SIGNAL_handler_install (SIGINT, &sighandler_shutdown); |
520 | shc_term = GNUNET_SIGNAL_handler_install (SIGTERM, &sighandler_shutdown); | 538 | shc_term = GNUNET_SIGNAL_handler_install (SIGTERM, &sighandler_shutdown); |
521 | shc_quit = GNUNET_SIGNAL_handler_install (SIGQUIT, &sighandler_shutdown); | 539 | shc_quit = GNUNET_SIGNAL_handler_install (SIGQUIT, &sighandler_shutdown); |
522 | shc_hup = GNUNET_SIGNAL_handler_install (SIGHUP, &sighandler_shutdown); | 540 | shc_hup = GNUNET_SIGNAL_handler_install (SIGHUP, &sighandler_shutdown); |
523 | #endif | 541 | #endif |
524 | memset (&sched, 0, sizeof (sched)); | 542 | memset (&sched, 0, sizeof (sched)); |
525 | sched.current_priority = GNUNET_SCHEDULER_PRIORITY_DEFAULT; | 543 | sched.current_priority = GNUNET_SCHEDULER_PRIORITY_DEFAULT; |
526 | GNUNET_SCHEDULER_add_continuation (&sched, | 544 | GNUNET_SCHEDULER_add_continuation (&sched, |
527 | GNUNET_YES, | ||
528 | task, | 545 | task, |
529 | cls, GNUNET_SCHEDULER_REASON_STARTUP); | 546 | task_cls, |
547 | GNUNET_SCHEDULER_REASON_STARTUP); | ||
530 | last_tr = 0; | 548 | last_tr = 0; |
531 | busy_wait_warning = 0; | 549 | busy_wait_warning = 0; |
532 | while ((GNUNET_NO == sched.shutdown) && | 550 | while ( (sched.pending != NULL) || (sched.ready_count > 0) ) |
533 | ((sched.pending != NULL) || (sched.ready_count > 0))) | ||
534 | { | 551 | { |
535 | GNUNET_NETWORK_fdset_zero (rs); | 552 | GNUNET_NETWORK_fdset_zero (rs); |
536 | GNUNET_NETWORK_fdset_zero (ws); | 553 | GNUNET_NETWORK_fdset_zero (ws); |
537 | timeout = GNUNET_TIME_relative_get_forever (); | 554 | timeout = GNUNET_TIME_UNIT_FOREVER_REL; |
538 | update_sets (&sched, rs, ws, &timeout); | 555 | update_sets (&sched, rs, ws, &timeout); |
539 | #ifndef MINGW | ||
540 | GNUNET_NETWORK_fdset_handle_set (rs, pr); | 556 | GNUNET_NETWORK_fdset_handle_set (rs, pr); |
541 | #endif | ||
542 | if (sched.ready_count > 0) | 557 | if (sched.ready_count > 0) |
543 | { | 558 | { |
544 | /* no blocking, more work already ready! */ | 559 | /* no blocking, more work already ready! */ |
545 | timeout = GNUNET_TIME_relative_get_zero (); | 560 | timeout = GNUNET_TIME_UNIT_ZERO; |
546 | } | 561 | } |
547 | ret = GNUNET_NETWORK_socket_select (rs, ws, NULL, timeout); | 562 | ret = GNUNET_NETWORK_socket_select (rs, ws, NULL, timeout); |
548 | #ifndef MINGW | 563 | #ifndef MINGW |
549 | if (GNUNET_NETWORK_fdset_handle_isset (rs, pr)) | 564 | if (GNUNET_NETWORK_fdset_handle_isset (rs, pr)) |
550 | break; | 565 | { |
566 | /* consume the signal */ | ||
567 | GNUNET_DISK_file_read (pr, &c, sizeof(c)); | ||
568 | /* mark all active tasks as ready due to shutdown */ | ||
569 | GNUNET_SCHEDULER_shutdown (&sched); | ||
570 | } | ||
551 | #endif | 571 | #endif |
552 | if (last_tr == sched.tasks_run) | 572 | if (last_tr == sched.tasks_run) |
553 | { | 573 | { |
@@ -574,7 +594,6 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_Task task, void *cls) | |||
574 | check_ready (&sched, rs, ws); | 594 | check_ready (&sched, rs, ws); |
575 | run_ready (&sched); | 595 | run_ready (&sched); |
576 | } | 596 | } |
577 | sched.shutdown = GNUNET_YES; | ||
578 | #ifndef MINGW | 597 | #ifndef MINGW |
579 | GNUNET_SIGNAL_handler_uninstall (shc_int); | 598 | GNUNET_SIGNAL_handler_uninstall (shc_int); |
580 | GNUNET_SIGNAL_handler_uninstall (shc_term); | 599 | GNUNET_SIGNAL_handler_uninstall (shc_term); |
@@ -583,36 +602,11 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_Task task, void *cls) | |||
583 | GNUNET_DISK_pipe_close (sigpipe); | 602 | GNUNET_DISK_pipe_close (sigpipe); |
584 | sigpipe = NULL; | 603 | sigpipe = NULL; |
585 | #endif | 604 | #endif |
586 | do | ||
587 | { | ||
588 | run_ready (&sched); | ||
589 | check_ready (&sched, NULL, NULL); | ||
590 | } | ||
591 | while (sched.ready_count > 0); | ||
592 | while (NULL != (tpos = sched.pending)) | ||
593 | { | ||
594 | sched.pending = tpos->next; | ||
595 | GNUNET_free (tpos); | ||
596 | } | ||
597 | GNUNET_NETWORK_fdset_destroy (rs); | 605 | GNUNET_NETWORK_fdset_destroy (rs); |
598 | GNUNET_NETWORK_fdset_destroy (ws); | 606 | GNUNET_NETWORK_fdset_destroy (ws); |
599 | } | 607 | } |
600 | 608 | ||
601 | 609 | ||
602 | /** | ||
603 | * Request the shutdown of a scheduler. This function can be used to | ||
604 | * stop a scheduling thread when created with the | ||
605 | * "GNUNET_SCHEDULER_init_thread" function or from within the signal | ||
606 | * handler for signals causing shutdowns. | ||
607 | * | ||
608 | * @param sched the scheduler | ||
609 | */ | ||
610 | void | ||
611 | GNUNET_SCHEDULER_shutdown (struct GNUNET_SCHEDULER_Handle *sched) | ||
612 | { | ||
613 | sched->shutdown = GNUNET_YES; | ||
614 | } | ||
615 | |||
616 | 610 | ||
617 | /** | 611 | /** |
618 | * Get information about the current load of this scheduler. Use this | 612 | * Get information about the current load of this scheduler. Use this |
@@ -715,102 +709,113 @@ GNUNET_SCHEDULER_cancel (struct GNUNET_SCHEDULER_Handle *sched, | |||
715 | * and the reason code can be specified. | 709 | * and the reason code can be specified. |
716 | * | 710 | * |
717 | * @param sched scheduler to use | 711 | * @param sched scheduler to use |
718 | * @param run_on_shutdown should this task be run if we are shutting down? | 712 | * @param task main function of the task |
719 | * @param main main function of the task | 713 | * @param task_cls closure for 'main' |
720 | * @param cls closure for 'main' | ||
721 | * @param reason reason for task invocation | 714 | * @param reason reason for task invocation |
722 | */ | 715 | */ |
723 | void | 716 | void |
724 | GNUNET_SCHEDULER_add_continuation (struct GNUNET_SCHEDULER_Handle *sched, | 717 | GNUNET_SCHEDULER_add_continuation (struct GNUNET_SCHEDULER_Handle *sched, |
725 | int run_on_shutdown, | 718 | GNUNET_SCHEDULER_Task task, |
726 | GNUNET_SCHEDULER_Task main, | 719 | void *task_cls, |
727 | void *cls, | ||
728 | enum GNUNET_SCHEDULER_Reason reason) | 720 | enum GNUNET_SCHEDULER_Reason reason) |
729 | { | 721 | { |
730 | struct Task *task; | 722 | struct Task *t; |
731 | 723 | ||
732 | task = GNUNET_malloc (sizeof (struct Task)); | 724 | t = GNUNET_malloc (sizeof (struct Task)); |
733 | task->callback = main; | 725 | t->callback = task; |
734 | task->callback_cls = cls; | 726 | t->callback_cls = task_cls; |
735 | task->id = ++sched->last_id; | 727 | t->id = ++sched->last_id; |
736 | task->reason = reason; | 728 | t->reason = reason; |
737 | task->priority = sched->current_priority; | 729 | t->priority = sched->current_priority; |
738 | task->run_on_shutdown = run_on_shutdown; | ||
739 | #if DEBUG_TASKS | 730 | #if DEBUG_TASKS |
740 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 731 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
741 | "Adding continuation task: %llu / %p\n", | 732 | "Adding continuation task: %llu / %p\n", |
742 | task->id, task->callback_cls); | 733 | t->id, t->callback_cls); |
743 | #endif | 734 | #endif |
744 | queue_ready_task (sched, task); | 735 | queue_ready_task (sched, t); |
745 | } | 736 | } |
746 | 737 | ||
747 | 738 | ||
739 | |||
748 | /** | 740 | /** |
749 | * Schedule a new task to be run after the specified | 741 | * Schedule a new task to be run after the specified prerequisite task |
750 | * prerequisite task has completed. | 742 | * has completed. It will be run with the priority of the calling |
743 | * task. | ||
751 | * | 744 | * |
752 | * @param sched scheduler to use | 745 | * @param sched scheduler to use |
753 | * @param run_on_shutdown run on shutdown? | ||
754 | * @param prio how important is this task? | ||
755 | * @param prerequisite_task run this task after the task with the given | 746 | * @param prerequisite_task run this task after the task with the given |
756 | * task identifier completes (and any of our other | 747 | * task identifier completes (and any of our other |
757 | * conditions, such as delay, read or write-readyness | 748 | * conditions, such as delay, read or write-readyness |
758 | * are satisfied). Use GNUNET_SCHEDULER_NO_TASK to not have any dependency | 749 | * are satisfied). Use GNUNET_SCHEDULER_NO_TASK to not have any dependency |
759 | * on completion of other tasks. | 750 | * on completion of other tasks (this will cause the task to run as |
760 | * @param main main function of the task | 751 | * soon as possible). |
761 | * @param cls closure for 'main' | 752 | * @param task main function of the task |
753 | * @param task_cls closure of task | ||
762 | * @return unique task identifier for the job | 754 | * @return unique task identifier for the job |
763 | * only valid until "main" is started! | 755 | * only valid until "task" is started! |
764 | */ | 756 | */ |
765 | GNUNET_SCHEDULER_TaskIdentifier | 757 | GNUNET_SCHEDULER_TaskIdentifier |
766 | GNUNET_SCHEDULER_add_after (struct GNUNET_SCHEDULER_Handle *sched, | 758 | GNUNET_SCHEDULER_add_after (struct GNUNET_SCHEDULER_Handle *sched, |
767 | int run_on_shutdown, | ||
768 | enum GNUNET_SCHEDULER_Priority prio, | ||
769 | GNUNET_SCHEDULER_TaskIdentifier prerequisite_task, | 759 | GNUNET_SCHEDULER_TaskIdentifier prerequisite_task, |
770 | GNUNET_SCHEDULER_Task main, void *cls) | 760 | GNUNET_SCHEDULER_Task task, |
761 | void *task_cls) | ||
771 | { | 762 | { |
772 | return GNUNET_SCHEDULER_add_select (sched, run_on_shutdown, prio, | 763 | return GNUNET_SCHEDULER_add_select (sched, |
764 | GNUNET_SCHEDULER_PRIORITY_KEEP, | ||
773 | prerequisite_task, | 765 | prerequisite_task, |
774 | GNUNET_TIME_UNIT_ZERO, | 766 | GNUNET_TIME_UNIT_ZERO, |
775 | NULL, NULL, main, cls); | 767 | NULL, NULL, task, task_cls); |
776 | } | 768 | } |
777 | 769 | ||
778 | 770 | ||
779 | /** | 771 | /** |
772 | * Schedule a new task to be run with a specified priority. | ||
773 | * | ||
774 | * @param sched scheduler to use | ||
775 | * @param prio how important is the new task? | ||
776 | * @param task main function of the task | ||
777 | * @param task_cls closure of task | ||
778 | * @return unique task identifier for the job | ||
779 | * only valid until "task" is started! | ||
780 | */ | ||
781 | GNUNET_SCHEDULER_TaskIdentifier | ||
782 | GNUNET_SCHEDULER_add_with_priority (struct GNUNET_SCHEDULER_Handle *sched, | ||
783 | enum GNUNET_SCHEDULER_Priority prio, | ||
784 | GNUNET_SCHEDULER_Task task, | ||
785 | void *task_cls) | ||
786 | { | ||
787 | return GNUNET_SCHEDULER_add_select (sched, | ||
788 | prio, | ||
789 | GNUNET_SCHEDULER_NO_TASK, | ||
790 | GNUNET_TIME_UNIT_ZERO, | ||
791 | NULL, NULL, task, task_cls); | ||
792 | } | ||
793 | |||
794 | |||
795 | |||
796 | /** | ||
780 | * Schedule a new task to be run with a specified delay. The task | 797 | * Schedule a new task to be run with a specified delay. The task |
781 | * will be scheduled for execution once the delay has expired and the | 798 | * will be scheduled for execution once the delay has expired. It |
782 | * prerequisite task has completed. | 799 | * will be run with the priority of the calling task. |
783 | * | 800 | * |
784 | * @param sched scheduler to use | 801 | * @param sched scheduler to use |
785 | * @param run_on_shutdown run on shutdown? You can use this | 802 | * @param delay when should this operation time out? Use |
786 | * argument to run a function only during shutdown | 803 | * GNUNET_TIME_UNIT_FOREVER_REL for "on shutdown" |
787 | * by setting delay to -1. Set this | 804 | * @param task main function of the task |
788 | * argument to GNUNET_NO to skip this task if | 805 | * @param task_cls closure of task |
789 | * the user requested process termination. | ||
790 | * @param prio how important is this task? | ||
791 | * @param prerequisite_task run this task after the task with the given | ||
792 | * task identifier completes (and any of our other | ||
793 | * conditions, such as delay, read or write-readyness | ||
794 | * are satisfied). Use GNUNET_SCHEDULER_NO_TASK to not have any dependency | ||
795 | * on completion of other tasks. | ||
796 | * @param delay how long should we wait? Use GNUNET_TIME_UNIT_FOREVER_REL for "forever" | ||
797 | * @param main main function of the task | ||
798 | * @param cls closure of task | ||
799 | * @return unique task identifier for the job | 806 | * @return unique task identifier for the job |
800 | * only valid until "main" is started! | 807 | * only valid until "task" is started! |
801 | */ | 808 | */ |
802 | GNUNET_SCHEDULER_TaskIdentifier | 809 | GNUNET_SCHEDULER_TaskIdentifier |
803 | GNUNET_SCHEDULER_add_delayed (struct GNUNET_SCHEDULER_Handle * sched, | 810 | GNUNET_SCHEDULER_add_delayed (struct GNUNET_SCHEDULER_Handle *sched, |
804 | int run_on_shutdown, | ||
805 | enum GNUNET_SCHEDULER_Priority prio, | ||
806 | GNUNET_SCHEDULER_TaskIdentifier | ||
807 | prerequisite_task, | ||
808 | struct GNUNET_TIME_Relative delay, | 811 | struct GNUNET_TIME_Relative delay, |
809 | GNUNET_SCHEDULER_Task main, void *cls) | 812 | GNUNET_SCHEDULER_Task task, |
813 | void *task_cls) | ||
810 | { | 814 | { |
811 | return GNUNET_SCHEDULER_add_select (sched, run_on_shutdown, prio, | 815 | return GNUNET_SCHEDULER_add_select (sched, |
812 | prerequisite_task, delay, | 816 | GNUNET_SCHEDULER_PRIORITY_KEEP, |
813 | NULL, NULL, main, cls); | 817 | GNUNET_SCHEDULER_NO_TASK, delay, |
818 | NULL, NULL, task, task_cls); | ||
814 | } | 819 | } |
815 | 820 | ||
816 | 821 | ||
@@ -819,34 +824,24 @@ GNUNET_SCHEDULER_add_delayed (struct GNUNET_SCHEDULER_Handle * sched, | |||
819 | * specified file descriptor is ready for reading. The delay can be | 824 | * specified file descriptor is ready for reading. The delay can be |
820 | * used as a timeout on the socket being ready. The task will be | 825 | * used as a timeout on the socket being ready. The task will be |
821 | * scheduled for execution once either the delay has expired or the | 826 | * scheduled for execution once either the delay has expired or the |
822 | * socket operation is ready. | 827 | * socket operation is ready. It will be run with the priority of |
828 | * the calling task. | ||
823 | * | 829 | * |
824 | * @param sched scheduler to use | 830 | * @param sched scheduler to use |
825 | * @param run_on_shutdown run on shutdown? Set this | 831 | * @param delay when should this operation time out? Use |
826 | * argument to GNUNET_NO to skip this task if | 832 | * GNUNET_TIME_UNIT_FOREVER_REL for "on shutdown" |
827 | * the user requested process termination. | ||
828 | * @param prio how important is this task? | ||
829 | * @param prerequisite_task run this task after the task with the given | ||
830 | * task identifier completes (and any of our other | ||
831 | * conditions, such as delay, read or write-readyness | ||
832 | * are satisfied). Use GNUNET_SCHEDULER_NO_TASK to not have any dependency | ||
833 | * on completion of other tasks. | ||
834 | * @param delay how long should we wait? Use GNUNET_TIME_UNIT_FOREVER_REL for "forever" | ||
835 | * @param rfd read file-descriptor | 833 | * @param rfd read file-descriptor |
836 | * @param main main function of the task | 834 | * @param task main function of the task |
837 | * @param cls closure of task | 835 | * @param task_cls closure of task |
838 | * @return unique task identifier for the job | 836 | * @return unique task identifier for the job |
839 | * only valid until "main" is started! | 837 | * only valid until "task" is started! |
840 | */ | 838 | */ |
841 | GNUNET_SCHEDULER_TaskIdentifier | 839 | GNUNET_SCHEDULER_TaskIdentifier |
842 | GNUNET_SCHEDULER_add_read_net (struct GNUNET_SCHEDULER_Handle * sched, | 840 | GNUNET_SCHEDULER_add_read_net (struct GNUNET_SCHEDULER_Handle *sched, |
843 | int run_on_shutdown, | 841 | struct GNUNET_TIME_Relative delay, |
844 | enum GNUNET_SCHEDULER_Priority prio, | 842 | struct GNUNET_NETWORK_Handle *rfd, |
845 | GNUNET_SCHEDULER_TaskIdentifier | 843 | GNUNET_SCHEDULER_Task task, |
846 | prerequisite_task, | 844 | void *task_cls) |
847 | struct GNUNET_TIME_Relative delay, | ||
848 | struct GNUNET_NETWORK_Handle * rfd, | ||
849 | GNUNET_SCHEDULER_Task main, void *cls) | ||
850 | { | 845 | { |
851 | struct GNUNET_NETWORK_FDSet *rs; | 846 | struct GNUNET_NETWORK_FDSet *rs; |
852 | GNUNET_SCHEDULER_TaskIdentifier ret; | 847 | GNUNET_SCHEDULER_TaskIdentifier ret; |
@@ -854,9 +849,11 @@ GNUNET_SCHEDULER_add_read_net (struct GNUNET_SCHEDULER_Handle * sched, | |||
854 | GNUNET_assert (rfd != NULL); | 849 | GNUNET_assert (rfd != NULL); |
855 | rs = GNUNET_NETWORK_fdset_create (); | 850 | rs = GNUNET_NETWORK_fdset_create (); |
856 | GNUNET_NETWORK_fdset_set (rs, rfd); | 851 | GNUNET_NETWORK_fdset_set (rs, rfd); |
857 | ret = GNUNET_SCHEDULER_add_select (sched, run_on_shutdown, prio, | 852 | ret = GNUNET_SCHEDULER_add_select (sched, |
858 | prerequisite_task, delay, | 853 | GNUNET_SCHEDULER_PRIORITY_KEEP, |
859 | rs, NULL, main, cls); | 854 | GNUNET_SCHEDULER_NO_TASK, |
855 | delay, | ||
856 | rs, NULL, task, task_cls); | ||
860 | GNUNET_NETWORK_fdset_destroy (rs); | 857 | GNUNET_NETWORK_fdset_destroy (rs); |
861 | return ret; | 858 | return ret; |
862 | } | 859 | } |
@@ -867,34 +864,24 @@ GNUNET_SCHEDULER_add_read_net (struct GNUNET_SCHEDULER_Handle * sched, | |||
867 | * specified file descriptor is ready for writing. The delay can be | 864 | * specified file descriptor is ready for writing. The delay can be |
868 | * used as a timeout on the socket being ready. The task will be | 865 | * used as a timeout on the socket being ready. The task will be |
869 | * scheduled for execution once either the delay has expired or the | 866 | * scheduled for execution once either the delay has expired or the |
870 | * socket operation is ready. | 867 | * socket operation is ready. It will be run with the priority of |
868 | * the calling task. | ||
871 | * | 869 | * |
872 | * @param sched scheduler to use | 870 | * @param sched scheduler to use |
873 | * @param run_on_shutdown run on shutdown? Set this | 871 | * @param delay when should this operation time out? Use |
874 | * argument to GNUNET_NO to skip this task if | 872 | * GNUNET_TIME_UNIT_FOREVER_REL for "on shutdown" |
875 | * the user requested process termination. | ||
876 | * @param prio how important is this task? | ||
877 | * @param prerequisite_task run this task after the task with the given | ||
878 | * task identifier completes (and any of our other | ||
879 | * conditions, such as delay, read or write-readyness | ||
880 | * are satisfied). Use GNUNET_SCHEDULER_NO_TASK to not have any dependency | ||
881 | * on completion of other tasks. | ||
882 | * @param delay how long should we wait? Use GNUNET_TIME_UNIT_FOREVER_REL for "forever" | ||
883 | * @param wfd write file-descriptor | 873 | * @param wfd write file-descriptor |
884 | * @param main main function of the task | 874 | * @param task main function of the task |
885 | * @param cls closure of task | 875 | * @param task_cls closure of task |
886 | * @return unique task identifier for the job | 876 | * @return unique task identifier for the job |
887 | * only valid until "main" is started! | 877 | * only valid until "task" is started! |
888 | */ | 878 | */ |
889 | GNUNET_SCHEDULER_TaskIdentifier | 879 | GNUNET_SCHEDULER_TaskIdentifier |
890 | GNUNET_SCHEDULER_add_write_net (struct GNUNET_SCHEDULER_Handle * sched, | 880 | GNUNET_SCHEDULER_add_write_net (struct GNUNET_SCHEDULER_Handle *sched, |
891 | int run_on_shutdown, | 881 | struct GNUNET_TIME_Relative delay, |
892 | enum GNUNET_SCHEDULER_Priority prio, | 882 | struct GNUNET_NETWORK_Handle *wfd, |
893 | GNUNET_SCHEDULER_TaskIdentifier | 883 | GNUNET_SCHEDULER_Task task, |
894 | prerequisite_task, | 884 | void *task_cls) |
895 | struct GNUNET_TIME_Relative delay, | ||
896 | struct GNUNET_NETWORK_Handle * wfd, | ||
897 | GNUNET_SCHEDULER_Task main, void *cls) | ||
898 | { | 885 | { |
899 | struct GNUNET_NETWORK_FDSet *ws; | 886 | struct GNUNET_NETWORK_FDSet *ws; |
900 | GNUNET_SCHEDULER_TaskIdentifier ret; | 887 | GNUNET_SCHEDULER_TaskIdentifier ret; |
@@ -902,14 +889,95 @@ GNUNET_SCHEDULER_add_write_net (struct GNUNET_SCHEDULER_Handle * sched, | |||
902 | GNUNET_assert (wfd != NULL); | 889 | GNUNET_assert (wfd != NULL); |
903 | ws = GNUNET_NETWORK_fdset_create (); | 890 | ws = GNUNET_NETWORK_fdset_create (); |
904 | GNUNET_NETWORK_fdset_set (ws, wfd); | 891 | GNUNET_NETWORK_fdset_set (ws, wfd); |
905 | ret = GNUNET_SCHEDULER_add_select (sched, run_on_shutdown, prio, | 892 | ret = GNUNET_SCHEDULER_add_select (sched, |
906 | prerequisite_task, delay, | 893 | GNUNET_SCHEDULER_PRIORITY_KEEP, |
907 | NULL, ws, main, cls); | 894 | GNUNET_SCHEDULER_NO_TASK, delay, |
895 | NULL, ws, task, task_cls); | ||
896 | GNUNET_NETWORK_fdset_destroy (ws); | ||
897 | return ret; | ||
898 | } | ||
899 | |||
900 | |||
901 | /** | ||
902 | * Schedule a new task to be run with a specified delay or when the | ||
903 | * specified file descriptor is ready for reading. The delay can be | ||
904 | * used as a timeout on the socket being ready. The task will be | ||
905 | * scheduled for execution once either the delay has expired or the | ||
906 | * socket operation is ready. It will be run with the priority of | ||
907 | * the calling task. | ||
908 | * | ||
909 | * @param sched scheduler to use | ||
910 | * @param delay when should this operation time out? Use | ||
911 | * GNUNET_TIME_UNIT_FOREVER_REL for "on shutdown" | ||
912 | * @param rfd read file-descriptor | ||
913 | * @param task main function of the task | ||
914 | * @param task_cls closure of task | ||
915 | * @return unique task identifier for the job | ||
916 | * only valid until "task" is started! | ||
917 | */ | ||
918 | GNUNET_SCHEDULER_TaskIdentifier | ||
919 | GNUNET_SCHEDULER_add_read_file (struct GNUNET_SCHEDULER_Handle *sched, | ||
920 | struct GNUNET_TIME_Relative delay, | ||
921 | const struct GNUNET_DISK_FileHandle *rfd, | ||
922 | GNUNET_SCHEDULER_Task task, | ||
923 | void *task_cls) | ||
924 | { | ||
925 | struct GNUNET_NETWORK_FDSet *rs; | ||
926 | GNUNET_SCHEDULER_TaskIdentifier ret; | ||
927 | |||
928 | GNUNET_assert (rfd != NULL); | ||
929 | rs = GNUNET_NETWORK_fdset_create (); | ||
930 | GNUNET_NETWORK_fdset_handle_set (rs, rfd); | ||
931 | ret = GNUNET_SCHEDULER_add_select (sched, | ||
932 | GNUNET_SCHEDULER_PRIORITY_KEEP, | ||
933 | GNUNET_SCHEDULER_NO_TASK, delay, | ||
934 | rs, NULL, task, task_cls); | ||
935 | GNUNET_NETWORK_fdset_destroy (rs); | ||
936 | return ret; | ||
937 | } | ||
938 | |||
939 | |||
940 | /** | ||
941 | * Schedule a new task to be run with a specified delay or when the | ||
942 | * specified file descriptor is ready for writing. The delay can be | ||
943 | * used as a timeout on the socket being ready. The task will be | ||
944 | * scheduled for execution once either the delay has expired or the | ||
945 | * socket operation is ready. It will be run with the priority of | ||
946 | * the calling task. | ||
947 | * | ||
948 | * @param sched scheduler to use | ||
949 | * @param delay when should this operation time out? Use | ||
950 | * GNUNET_TIME_UNIT_FOREVER_REL for "on shutdown" | ||
951 | * @param wfd write file-descriptor | ||
952 | * @param task main function of the task | ||
953 | * @param task_cls closure of task | ||
954 | * @return unique task identifier for the job | ||
955 | * only valid until "task" is started! | ||
956 | */ | ||
957 | GNUNET_SCHEDULER_TaskIdentifier | ||
958 | GNUNET_SCHEDULER_add_write_file (struct GNUNET_SCHEDULER_Handle *sched, | ||
959 | struct GNUNET_TIME_Relative delay, | ||
960 | const struct GNUNET_DISK_FileHandle *wfd, | ||
961 | GNUNET_SCHEDULER_Task task, | ||
962 | void *task_cls) | ||
963 | { | ||
964 | struct GNUNET_NETWORK_FDSet *ws; | ||
965 | GNUNET_SCHEDULER_TaskIdentifier ret; | ||
966 | |||
967 | GNUNET_assert (wfd != NULL); | ||
968 | ws = GNUNET_NETWORK_fdset_create (); | ||
969 | GNUNET_NETWORK_fdset_handle_set (ws, wfd); | ||
970 | ret = GNUNET_SCHEDULER_add_select (sched, | ||
971 | GNUNET_SCHEDULER_PRIORITY_KEEP, | ||
972 | GNUNET_SCHEDULER_NO_TASK, | ||
973 | delay, | ||
974 | NULL, ws, task, task_cls); | ||
908 | GNUNET_NETWORK_fdset_destroy (ws); | 975 | GNUNET_NETWORK_fdset_destroy (ws); |
909 | return ret; | 976 | return ret; |
910 | } | 977 | } |
911 | 978 | ||
912 | 979 | ||
980 | |||
913 | /** | 981 | /** |
914 | * Schedule a new task to be run with a specified delay or when any of | 982 | * Schedule a new task to be run with a specified delay or when any of |
915 | * the specified file descriptor sets is ready. The delay can be used | 983 | * the specified file descriptor sets is ready. The delay can be used |
@@ -928,160 +996,61 @@ GNUNET_SCHEDULER_add_write_net (struct GNUNET_SCHEDULER_Handle * sched, | |||
928 | * </code> | 996 | * </code> |
929 | * | 997 | * |
930 | * @param sched scheduler to use | 998 | * @param sched scheduler to use |
931 | * @param run_on_shutdown run on shutdown? Set this | ||
932 | * argument to GNUNET_NO to skip this task if | ||
933 | * the user requested process termination. | ||
934 | * @param prio how important is this task? | 999 | * @param prio how important is this task? |
935 | * @param prerequisite_task run this task after the task with the given | 1000 | * @param prerequisite_task run this task after the task with the given |
936 | * task identifier completes (and any of our other | 1001 | * task identifier completes (and any of our other |
937 | * conditions, such as delay, read or write-readyness | 1002 | * conditions, such as delay, read or write-readyness |
938 | * are satisfied). Use GNUNET_SCHEDULER_NO_TASK to not have any dependency | 1003 | * are satisfied). Use GNUNET_SCHEDULER_NO_TASK to not have any dependency |
939 | * on completion of other tasks. | 1004 | * on completion of other tasks. |
940 | * @param delay how long should we wait? Use GNUNET_TIME_UNIT_FOREVER_REL for "forever" | 1005 | * @param delay how long should we wait? Use GNUNET_TIME_UNIT_FOREVER_REL for "forever", |
1006 | * which means that the task will only be run after we receive SIGTERM | ||
941 | * @param rs set of file descriptors we want to read (can be NULL) | 1007 | * @param rs set of file descriptors we want to read (can be NULL) |
942 | * @param ws set of file descriptors we want to write (can be NULL) | 1008 | * @param ws set of file descriptors we want to write (can be NULL) |
943 | * @param main main function of the task | 1009 | * @param task main function of the task |
944 | * @param cls closure of task | 1010 | * @param task_cls closure of task |
945 | * @return unique task identifier for the job | 1011 | * @return unique task identifier for the job |
946 | * only valid until "main" is started! | 1012 | * only valid until "task" is started! |
947 | */ | 1013 | */ |
948 | GNUNET_SCHEDULER_TaskIdentifier | 1014 | GNUNET_SCHEDULER_TaskIdentifier |
949 | GNUNET_SCHEDULER_add_select (struct GNUNET_SCHEDULER_Handle * sched, | 1015 | GNUNET_SCHEDULER_add_select (struct GNUNET_SCHEDULER_Handle *sched, |
950 | int run_on_shutdown, | ||
951 | enum GNUNET_SCHEDULER_Priority prio, | 1016 | enum GNUNET_SCHEDULER_Priority prio, |
952 | GNUNET_SCHEDULER_TaskIdentifier | 1017 | GNUNET_SCHEDULER_TaskIdentifier |
953 | prerequisite_task, | 1018 | prerequisite_task, |
954 | struct GNUNET_TIME_Relative delay, | 1019 | struct GNUNET_TIME_Relative delay, |
955 | const struct GNUNET_NETWORK_FDSet * rs, | 1020 | const struct GNUNET_NETWORK_FDSet * rs, |
956 | const struct GNUNET_NETWORK_FDSet * ws, | 1021 | const struct GNUNET_NETWORK_FDSet * ws, |
957 | GNUNET_SCHEDULER_Task main, void *cls) | 1022 | GNUNET_SCHEDULER_Task task, |
1023 | void *task_cls) | ||
958 | { | 1024 | { |
959 | struct Task *task; | 1025 | struct Task *t; |
960 | 1026 | ||
961 | task = GNUNET_malloc (sizeof (struct Task)); | 1027 | t = GNUNET_malloc (sizeof (struct Task)); |
962 | task->callback = main; | 1028 | t->callback = task; |
963 | task->callback_cls = cls; | 1029 | t->callback_cls = task_cls; |
964 | if (rs != NULL) | 1030 | if (rs != NULL) |
965 | { | 1031 | { |
966 | task->read_set = GNUNET_NETWORK_fdset_create (); | 1032 | t->read_set = GNUNET_NETWORK_fdset_create (); |
967 | GNUNET_NETWORK_fdset_copy (task->read_set, rs); | 1033 | GNUNET_NETWORK_fdset_copy (t->read_set, rs); |
968 | } | 1034 | } |
969 | if (ws != NULL) | 1035 | if (ws != NULL) |
970 | { | 1036 | { |
971 | task->write_set = GNUNET_NETWORK_fdset_create (); | 1037 | t->write_set = GNUNET_NETWORK_fdset_create (); |
972 | GNUNET_NETWORK_fdset_copy (task->write_set, ws); | 1038 | GNUNET_NETWORK_fdset_copy (t->write_set, ws); |
973 | } | 1039 | } |
974 | task->id = ++sched->last_id; | 1040 | t->id = ++sched->last_id; |
975 | task->prereq_id = prerequisite_task; | 1041 | t->prereq_id = prerequisite_task; |
976 | task->timeout = GNUNET_TIME_relative_to_absolute (delay); | 1042 | t->timeout = GNUNET_TIME_relative_to_absolute (delay); |
977 | task->priority = | 1043 | t->priority = |
978 | check_priority ((prio == | 1044 | check_priority ((prio == |
979 | GNUNET_SCHEDULER_PRIORITY_KEEP) ? sched->current_priority | 1045 | GNUNET_SCHEDULER_PRIORITY_KEEP) ? sched->current_priority |
980 | : prio); | 1046 | : prio); |
981 | task->run_on_shutdown = run_on_shutdown; | 1047 | t->next = sched->pending; |
982 | task->next = sched->pending; | 1048 | sched->pending = t; |
983 | sched->pending = task; | ||
984 | #if DEBUG_TASKS | 1049 | #if DEBUG_TASKS |
985 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1050 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
986 | "Adding task: %llu / %p\n", task->id, task->callback_cls); | 1051 | "Adding task: %llu / %p\n", t->id, t->callback_cls); |
987 | #endif | 1052 | #endif |
988 | return task->id; | 1053 | return t->id; |
989 | } | 1054 | } |
990 | 1055 | ||
991 | /** | ||
992 | * Schedule a new task to be run with a specified delay or when the | ||
993 | * specified file descriptor is ready for reading. The delay can be | ||
994 | * used as a timeout on the socket being ready. The task will be | ||
995 | * scheduled for execution once either the delay has expired or the | ||
996 | * socket operation is ready. | ||
997 | * | ||
998 | * @param sched scheduler to use | ||
999 | * @param run_on_shutdown run on shutdown? Set this | ||
1000 | * argument to GNUNET_NO to skip this task if | ||
1001 | * the user requested process termination. | ||
1002 | * @param prio how important is this task? | ||
1003 | * @param prerequisite_task run this task after the task with the given | ||
1004 | * task identifier completes (and any of our other | ||
1005 | * conditions, such as delay, read or write-readyness | ||
1006 | * are satisfied). Use GNUNET_SCHEDULER_NO_TASK to not have any dependency | ||
1007 | * on completion of other tasks. | ||
1008 | * @param delay how long should we wait? Use GNUNET_TIME_UNIT_FOREVER_REL for "forever" | ||
1009 | * @param rfd read file-descriptor | ||
1010 | * @param main main function of the task | ||
1011 | * @param cls closure of task | ||
1012 | * @return unique task identifier for the job | ||
1013 | * only valid until "main" is started! | ||
1014 | */ | ||
1015 | GNUNET_SCHEDULER_TaskIdentifier | ||
1016 | GNUNET_SCHEDULER_add_read_file (struct GNUNET_SCHEDULER_Handle * sched, | ||
1017 | int run_on_shutdown, | ||
1018 | enum GNUNET_SCHEDULER_Priority prio, | ||
1019 | GNUNET_SCHEDULER_TaskIdentifier | ||
1020 | prerequisite_task, | ||
1021 | struct GNUNET_TIME_Relative delay, | ||
1022 | const struct GNUNET_DISK_FileHandle * rfd, | ||
1023 | GNUNET_SCHEDULER_Task main, void *cls) | ||
1024 | { | ||
1025 | struct GNUNET_NETWORK_FDSet *rs; | ||
1026 | GNUNET_SCHEDULER_TaskIdentifier ret; | ||
1027 | |||
1028 | GNUNET_assert (rfd != NULL); | ||
1029 | rs = GNUNET_NETWORK_fdset_create (); | ||
1030 | GNUNET_NETWORK_fdset_handle_set (rs, rfd); | ||
1031 | ret = GNUNET_SCHEDULER_add_select (sched, run_on_shutdown, prio, | ||
1032 | prerequisite_task, delay, | ||
1033 | rs, NULL, main, cls); | ||
1034 | GNUNET_NETWORK_fdset_destroy (rs); | ||
1035 | return ret; | ||
1036 | } | ||
1037 | |||
1038 | |||
1039 | /** | ||
1040 | * Schedule a new task to be run with a specified delay or when the | ||
1041 | * specified file descriptor is ready for writing. The delay can be | ||
1042 | * used as a timeout on the socket being ready. The task will be | ||
1043 | * scheduled for execution once either the delay has expired or the | ||
1044 | * socket operation is ready. | ||
1045 | * | ||
1046 | * @param sched scheduler to use | ||
1047 | * @param run_on_shutdown run on shutdown? Set this | ||
1048 | * argument to GNUNET_NO to skip this task if | ||
1049 | * the user requested process termination. | ||
1050 | * @param prio how important is this task? | ||
1051 | * @param prerequisite_task run this task after the task with the given | ||
1052 | * task identifier completes (and any of our other | ||
1053 | * conditions, such as delay, read or write-readyness | ||
1054 | * are satisfied). Use GNUNET_SCHEDULER_NO_TASK to not have any dependency | ||
1055 | * on completion of other tasks. | ||
1056 | * @param delay how long should we wait? Use GNUNET_TIME_UNIT_FOREVER_REL for "forever" | ||
1057 | * @param wfd write file-descriptor | ||
1058 | * @param main main function of the task | ||
1059 | * @param cls closure of task | ||
1060 | * @return unique task identifier for the job | ||
1061 | * only valid until "main" is started! | ||
1062 | */ | ||
1063 | GNUNET_SCHEDULER_TaskIdentifier | ||
1064 | GNUNET_SCHEDULER_add_write_file (struct GNUNET_SCHEDULER_Handle * sched, | ||
1065 | int run_on_shutdown, | ||
1066 | enum GNUNET_SCHEDULER_Priority prio, | ||
1067 | GNUNET_SCHEDULER_TaskIdentifier | ||
1068 | prerequisite_task, | ||
1069 | struct GNUNET_TIME_Relative delay, | ||
1070 | const struct GNUNET_DISK_FileHandle * wfd, | ||
1071 | GNUNET_SCHEDULER_Task main, void *cls) | ||
1072 | { | ||
1073 | struct GNUNET_NETWORK_FDSet *ws; | ||
1074 | GNUNET_SCHEDULER_TaskIdentifier ret; | ||
1075 | |||
1076 | GNUNET_assert (wfd != NULL); | ||
1077 | ws = GNUNET_NETWORK_fdset_create (); | ||
1078 | GNUNET_NETWORK_fdset_handle_set (ws, wfd); | ||
1079 | ret = GNUNET_SCHEDULER_add_select (sched, run_on_shutdown, prio, | ||
1080 | prerequisite_task, delay, | ||
1081 | NULL, ws, main, cls); | ||
1082 | GNUNET_NETWORK_fdset_destroy (ws); | ||
1083 | return ret; | ||
1084 | } | ||
1085 | |||
1086 | |||
1087 | /* end of scheduler.c */ | 1056 | /* end of scheduler.c */ |