summaryrefslogtreecommitdiff
path: root/src/util/scheduler.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/scheduler.c')
-rw-r--r--src/util/scheduler.c1923
1 files changed, 960 insertions, 963 deletions
diff --git a/src/util/scheduler.c b/src/util/scheduler.c
index c818e91ee..4bea5bd5d 100644
--- a/src/util/scheduler.c
+++ b/src/util/scheduler.c
@@ -11,7 +11,7 @@
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU Affero General Public License 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/>. 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
@@ -28,9 +28,9 @@
28// DEBUG 28// DEBUG
29#include <inttypes.h> 29#include <inttypes.h>
30 30
31#define LOG(kind,...) GNUNET_log_from (kind, "util-scheduler", __VA_ARGS__) 31#define LOG(kind, ...) GNUNET_log_from(kind, "util-scheduler", __VA_ARGS__)
32 32
33#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-scheduler", syscall) 33#define LOG_STRERROR(kind, syscall) GNUNET_log_from_strerror(kind, "util-scheduler", syscall)
34 34
35 35
36#if HAVE_EXECINFO_H 36#if HAVE_EXECINFO_H
@@ -76,8 +76,7 @@
76 * #GNUNET_SCHEDULER_do_work(). Contains the 76 * #GNUNET_SCHEDULER_do_work(). Contains the
77 * scheduler's internal state. 77 * scheduler's internal state.
78 */ 78 */
79struct GNUNET_SCHEDULER_Handle 79struct GNUNET_SCHEDULER_Handle {
80{
81 /** 80 /**
82 * Passed here to avoid constantly allocating/deallocating 81 * Passed here to avoid constantly allocating/deallocating
83 * this element, but generally we want to get rid of this. 82 * this element, but generally we want to get rid of this.
@@ -131,8 +130,7 @@ struct GNUNET_SCHEDULER_Handle
131/** 130/**
132 * Entry in list of pending tasks. 131 * Entry in list of pending tasks.
133 */ 132 */
134struct GNUNET_SCHEDULER_Task 133struct GNUNET_SCHEDULER_Task {
135{
136 /** 134 /**
137 * This is a linked list. 135 * This is a linked list.
138 */ 136 */
@@ -245,15 +243,13 @@ struct GNUNET_SCHEDULER_Task
245 * Asynchronous scope of the task that scheduled this scope, 243 * Asynchronous scope of the task that scheduled this scope,
246 */ 244 */
247 struct GNUNET_AsyncScopeSave scope; 245 struct GNUNET_AsyncScopeSave scope;
248
249}; 246};
250 247
251 248
252/** 249/**
253 * A struct representing an event the select driver is waiting for 250 * A struct representing an event the select driver is waiting for
254 */ 251 */
255struct Scheduled 252struct Scheduled {
256{
257 struct Scheduled *prev; 253 struct Scheduled *prev;
258 254
259 struct Scheduled *next; 255 struct Scheduled *next;
@@ -280,8 +276,7 @@ struct Scheduled
280/** 276/**
281 * Driver context used by GNUNET_SCHEDULER_run 277 * Driver context used by GNUNET_SCHEDULER_run
282 */ 278 */
283struct DriverContext 279struct DriverContext {
284{
285 /** 280 /**
286 * the head of a DLL containing information about the events the 281 * the head of a DLL containing information about the events the
287 * select driver is waiting for 282 * select driver is waiting for
@@ -430,8 +425,8 @@ static void *scheduler_select_cls;
430 * @return previously used select function, NULL for default 425 * @return previously used select function, NULL for default
431 */ 426 */
432void 427void
433GNUNET_SCHEDULER_set_select (GNUNET_SCHEDULER_select new_select, 428GNUNET_SCHEDULER_set_select(GNUNET_SCHEDULER_select new_select,
434 void *new_select_cls) 429 void *new_select_cls)
435{ 430{
436 scheduler_select = new_select; 431 scheduler_select = new_select;
437 scheduler_select_cls = new_select_cls; 432 scheduler_select_cls = new_select_cls;
@@ -445,11 +440,11 @@ GNUNET_SCHEDULER_set_select (GNUNET_SCHEDULER_select new_select,
445 * @return p on success, 0 on error 440 * @return p on success, 0 on error
446 */ 441 */
447static enum GNUNET_SCHEDULER_Priority 442static enum GNUNET_SCHEDULER_Priority
448check_priority (enum GNUNET_SCHEDULER_Priority p) 443check_priority(enum GNUNET_SCHEDULER_Priority p)
449{ 444{
450 if ((p >= 0) && (p < GNUNET_SCHEDULER_PRIORITY_COUNT)) 445 if ((p >= 0) && (p < GNUNET_SCHEDULER_PRIORITY_COUNT))
451 return p; 446 return p;
452 GNUNET_assert (0); 447 GNUNET_assert(0);
453 return 0; /* make compiler happy */ 448 return 0; /* make compiler happy */
454} 449}
455 450
@@ -460,38 +455,38 @@ check_priority (enum GNUNET_SCHEDULER_Priority p)
460 * callback) 455 * callback)
461 */ 456 */
462struct GNUNET_TIME_Absolute 457struct GNUNET_TIME_Absolute
463get_timeout () 458get_timeout()
464{ 459{
465 struct GNUNET_SCHEDULER_Task *pos; 460 struct GNUNET_SCHEDULER_Task *pos;
466 struct GNUNET_TIME_Absolute now; 461 struct GNUNET_TIME_Absolute now;
467 struct GNUNET_TIME_Absolute timeout; 462 struct GNUNET_TIME_Absolute timeout;
468 463
469 pos = pending_timeout_head; 464 pos = pending_timeout_head;
470 now = GNUNET_TIME_absolute_get (); 465 now = GNUNET_TIME_absolute_get();
471 timeout = GNUNET_TIME_UNIT_FOREVER_ABS; 466 timeout = GNUNET_TIME_UNIT_FOREVER_ABS;
472 if (NULL != pos) 467 if (NULL != pos)
473 {
474 if (0 != pos->reason)
475 { 468 {
476 return now; 469 if (0 != pos->reason)
477 } 470 {
478 else 471 return now;
479 { 472 }
480 timeout = pos->timeout; 473 else
474 {
475 timeout = pos->timeout;
476 }
481 } 477 }
482 }
483 for (pos = pending_head; NULL != pos; pos = pos->next) 478 for (pos = pending_head; NULL != pos; pos = pos->next)
484 {
485 if (0 != pos->reason)
486 { 479 {
487 return now; 480 if (0 != pos->reason)
488 } 481 {
489 else if ((pos->timeout.abs_value_us != GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us) && 482 return now;
490 (timeout.abs_value_us > pos->timeout.abs_value_us)) 483 }
491 { 484 else if ((pos->timeout.abs_value_us != GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us) &&
492 timeout = pos->timeout; 485 (timeout.abs_value_us > pos->timeout.abs_value_us))
486 {
487 timeout = pos->timeout;
488 }
493 } 489 }
494 }
495 return timeout; 490 return timeout;
496} 491}
497 492
@@ -502,13 +497,13 @@ get_timeout ()
502 * @param task task ready for execution 497 * @param task task ready for execution
503 */ 498 */
504static void 499static void
505queue_ready_task (struct GNUNET_SCHEDULER_Task *task) 500queue_ready_task(struct GNUNET_SCHEDULER_Task *task)
506{ 501{
507 enum GNUNET_SCHEDULER_Priority p = check_priority (task->priority); 502 enum GNUNET_SCHEDULER_Priority p = check_priority(task->priority);
508 503
509 GNUNET_CONTAINER_DLL_insert (ready_head[p], 504 GNUNET_CONTAINER_DLL_insert(ready_head[p],
510 ready_tail[p], 505 ready_tail[p],
511 task); 506 task);
512 task->in_ready_list = GNUNET_YES; 507 task->in_ready_list = GNUNET_YES;
513 ready_count++; 508 ready_count++;
514} 509}
@@ -521,30 +516,30 @@ queue_ready_task (struct GNUNET_SCHEDULER_Task *task)
521 * will be delayed until the next shutdown signal. 516 * will be delayed until the next shutdown signal.
522 */ 517 */
523void 518void
524GNUNET_SCHEDULER_shutdown () 519GNUNET_SCHEDULER_shutdown()
525{ 520{
526 struct GNUNET_SCHEDULER_Task *pos; 521 struct GNUNET_SCHEDULER_Task *pos;
527 522
528 LOG (GNUNET_ERROR_TYPE_DEBUG, 523 LOG(GNUNET_ERROR_TYPE_DEBUG,
529 "GNUNET_SCHEDULER_shutdown\n"); 524 "GNUNET_SCHEDULER_shutdown\n");
530 if (NULL != install_parent_control_task) 525 if (NULL != install_parent_control_task)
531 { 526 {
532 GNUNET_SCHEDULER_cancel (install_parent_control_task); 527 GNUNET_SCHEDULER_cancel(install_parent_control_task);
533 install_parent_control_task = NULL; 528 install_parent_control_task = NULL;
534 } 529 }
535 if (NULL != shutdown_pipe_task) 530 if (NULL != shutdown_pipe_task)
536 { 531 {
537 GNUNET_SCHEDULER_cancel (shutdown_pipe_task); 532 GNUNET_SCHEDULER_cancel(shutdown_pipe_task);
538 shutdown_pipe_task = NULL; 533 shutdown_pipe_task = NULL;
539 } 534 }
540 while (NULL != (pos = shutdown_head)) 535 while (NULL != (pos = shutdown_head))
541 { 536 {
542 GNUNET_CONTAINER_DLL_remove (shutdown_head, 537 GNUNET_CONTAINER_DLL_remove(shutdown_head,
543 shutdown_tail, 538 shutdown_tail,
544 pos); 539 pos);
545 pos->reason |= GNUNET_SCHEDULER_REASON_SHUTDOWN; 540 pos->reason |= GNUNET_SCHEDULER_REASON_SHUTDOWN;
546 queue_ready_task (pos); 541 queue_ready_task(pos);
547 } 542 }
548} 543}
549 544
550 545
@@ -554,17 +549,17 @@ GNUNET_SCHEDULER_shutdown ()
554 * @param t task to dump stack trace of 549 * @param t task to dump stack trace of
555 */ 550 */
556static void 551static void
557dump_backtrace (struct GNUNET_SCHEDULER_Task *t) 552dump_backtrace(struct GNUNET_SCHEDULER_Task *t)
558{ 553{
559#if EXECINFO 554#if EXECINFO
560 for (unsigned int i = 0; i < t->num_backtrace_strings; i++) 555 for (unsigned int i = 0; i < t->num_backtrace_strings; i++)
561 LOG (GNUNET_ERROR_TYPE_WARNING, 556 LOG(GNUNET_ERROR_TYPE_WARNING,
562 "Task %p trace %u: %s\n", 557 "Task %p trace %u: %s\n",
563 t, 558 t,
564 i, 559 i,
565 t->backtrace_strings[i]); 560 t->backtrace_strings[i]);
566#else 561#else
567 (void) t; 562 (void)t;
568#endif 563#endif
569} 564}
570 565
@@ -575,40 +570,40 @@ dump_backtrace (struct GNUNET_SCHEDULER_Task *t)
575 * @param t task to destroy 570 * @param t task to destroy
576 */ 571 */
577static void 572static void
578destroy_task (struct GNUNET_SCHEDULER_Task *t) 573destroy_task(struct GNUNET_SCHEDULER_Task *t)
579{ 574{
580 unsigned int i; 575 unsigned int i;
581 576
582 LOG (GNUNET_ERROR_TYPE_DEBUG, 577 LOG(GNUNET_ERROR_TYPE_DEBUG,
583 "destroying task %p\n", 578 "destroying task %p\n",
584 t); 579 t);
585 580
586 if (GNUNET_YES == t->own_handles) 581 if (GNUNET_YES == t->own_handles)
587 {
588 for (i = 0; i != t->fds_len; ++i)
589 { 582 {
590 const struct GNUNET_NETWORK_Handle *fd = t->fds[i].fd; 583 for (i = 0; i != t->fds_len; ++i)
591 const struct GNUNET_DISK_FileHandle *fh = t->fds[i].fh; 584 {
592 if (fd) 585 const struct GNUNET_NETWORK_Handle *fd = t->fds[i].fd;
593 { 586 const struct GNUNET_DISK_FileHandle *fh = t->fds[i].fh;
594 GNUNET_NETWORK_socket_free_memory_only_ ((struct GNUNET_NETWORK_Handle *) fd); 587 if (fd)
595 } 588 {
596 if (fh) 589 GNUNET_NETWORK_socket_free_memory_only_((struct GNUNET_NETWORK_Handle *)fd);
597 { 590 }
598 // FIXME: on WIN32 this is not enough! A function 591 if (fh)
599 // GNUNET_DISK_file_free_memory_only would be nice 592 {
600 GNUNET_free ((void *) fh); 593 // FIXME: on WIN32 this is not enough! A function
601 } 594 // GNUNET_DISK_file_free_memory_only would be nice
595 GNUNET_free((void *)fh);
596 }
597 }
602 } 598 }
603 }
604 if (t->fds_len > 1) 599 if (t->fds_len > 1)
605 { 600 {
606 GNUNET_array_grow (t->fds, t->fds_len, 0); 601 GNUNET_array_grow(t->fds, t->fds_len, 0);
607 } 602 }
608#if EXECINFO 603#if EXECINFO
609 GNUNET_free (t->backtrace_strings); 604 GNUNET_free(t->backtrace_strings);
610#endif 605#endif
611 GNUNET_free (t); 606 GNUNET_free(t);
612} 607}
613 608
614 609
@@ -628,7 +623,7 @@ static pid_t my_pid;
628 */ 623 */
629#ifndef MINGW 624#ifndef MINGW
630static void 625static void
631sighandler_pipe () 626sighandler_pipe()
632{ 627{
633 return; 628 return;
634} 629}
@@ -657,23 +652,23 @@ sighandler_pipe ()
657 * Signal handler called for signals that should cause us to shutdown. 652 * Signal handler called for signals that should cause us to shutdown.
658 */ 653 */
659static void 654static void
660sighandler_shutdown () 655sighandler_shutdown()
661{ 656{
662 static char c; 657 static char c;
663 int old_errno = errno; /* backup errno */ 658 int old_errno = errno; /* backup errno */
664 659
665 if (getpid () != my_pid) 660 if (getpid() != my_pid)
666 _exit (1); /* we have fork'ed since the signal handler was created, 661 _exit(1); /* we have fork'ed since the signal handler was created,
667 * ignore the signal, see https://gnunet.org/vfork discussion */ 662 * ignore the signal, see https://gnunet.org/vfork discussion */
668 GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle 663 GNUNET_DISK_file_write(GNUNET_DISK_pipe_handle
669 (shutdown_pipe_handle, GNUNET_DISK_PIPE_END_WRITE), 664 (shutdown_pipe_handle, GNUNET_DISK_PIPE_END_WRITE),
670 &c, sizeof (c)); 665 &c, sizeof(c));
671 errno = old_errno; 666 errno = old_errno;
672} 667}
673 668
674 669
675static void 670static void
676shutdown_if_no_lifeness () 671shutdown_if_no_lifeness()
677{ 672{
678 struct GNUNET_SCHEDULER_Task *t; 673 struct GNUNET_SCHEDULER_Task *t;
679 674
@@ -689,13 +684,13 @@ shutdown_if_no_lifeness ()
689 if (GNUNET_YES == t->lifeness) 684 if (GNUNET_YES == t->lifeness)
690 return; 685 return;
691 /* No lifeness! */ 686 /* No lifeness! */
692 GNUNET_SCHEDULER_shutdown (); 687 GNUNET_SCHEDULER_shutdown();
693} 688}
694 689
695 690
696static int 691static int
697select_loop (struct GNUNET_SCHEDULER_Handle *sh, 692select_loop(struct GNUNET_SCHEDULER_Handle *sh,
698 struct DriverContext *context); 693 struct DriverContext *context);
699 694
700 695
701/** 696/**
@@ -713,26 +708,26 @@ select_loop (struct GNUNET_SCHEDULER_Handle *sh,
713 * @param task_cls closure of @a task 708 * @param task_cls closure of @a task
714 */ 709 */
715void 710void
716GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_TaskCallback task, 711GNUNET_SCHEDULER_run(GNUNET_SCHEDULER_TaskCallback task,
717 void *task_cls) 712 void *task_cls)
718{ 713{
719 struct GNUNET_SCHEDULER_Handle *sh; 714 struct GNUNET_SCHEDULER_Handle *sh;
720 struct GNUNET_SCHEDULER_Driver *driver; 715 struct GNUNET_SCHEDULER_Driver *driver;
721 struct DriverContext context = {.scheduled_head = NULL, 716 struct DriverContext context = { .scheduled_head = NULL,
722 .scheduled_tail = NULL, 717 .scheduled_tail = NULL,
723 .timeout = GNUNET_TIME_absolute_get ()}; 718 .timeout = GNUNET_TIME_absolute_get() };
724 719
725 driver = GNUNET_SCHEDULER_driver_select (); 720 driver = GNUNET_SCHEDULER_driver_select();
726 driver->cls = &context; 721 driver->cls = &context;
727 sh = GNUNET_SCHEDULER_driver_init (driver); 722 sh = GNUNET_SCHEDULER_driver_init(driver);
728 GNUNET_SCHEDULER_add_with_reason_and_priority (task, 723 GNUNET_SCHEDULER_add_with_reason_and_priority(task,
729 task_cls, 724 task_cls,
730 GNUNET_SCHEDULER_REASON_STARTUP, 725 GNUNET_SCHEDULER_REASON_STARTUP,
731 GNUNET_SCHEDULER_PRIORITY_DEFAULT); 726 GNUNET_SCHEDULER_PRIORITY_DEFAULT);
732 select_loop (sh, 727 select_loop(sh,
733 &context); 728 &context);
734 GNUNET_SCHEDULER_driver_done (sh); 729 GNUNET_SCHEDULER_driver_done(sh);
735 GNUNET_free (driver); 730 GNUNET_free(driver);
736} 731}
737 732
738 733
@@ -743,9 +738,9 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_TaskCallback task,
743 * @return current tasks' scheduler context 738 * @return current tasks' scheduler context
744 */ 739 */
745const struct GNUNET_SCHEDULER_TaskContext * 740const struct GNUNET_SCHEDULER_TaskContext *
746GNUNET_SCHEDULER_get_task_context () 741GNUNET_SCHEDULER_get_task_context()
747{ 742{
748 GNUNET_assert (NULL != active_task); 743 GNUNET_assert(NULL != active_task);
749 return &tc; 744 return &tc;
750} 745}
751 746
@@ -760,33 +755,33 @@ GNUNET_SCHEDULER_get_task_context ()
760 * @return number of tasks pending right now 755 * @return number of tasks pending right now
761 */ 756 */
762unsigned int 757unsigned int
763GNUNET_SCHEDULER_get_load (enum GNUNET_SCHEDULER_Priority p) 758GNUNET_SCHEDULER_get_load(enum GNUNET_SCHEDULER_Priority p)
764{ 759{
765 struct GNUNET_SCHEDULER_Task *pos; 760 struct GNUNET_SCHEDULER_Task *pos;
766 unsigned int ret; 761 unsigned int ret;
767 762
768 GNUNET_assert (NULL != active_task); 763 GNUNET_assert(NULL != active_task);
769 if (p == GNUNET_SCHEDULER_PRIORITY_COUNT) 764 if (p == GNUNET_SCHEDULER_PRIORITY_COUNT)
770 return ready_count; 765 return ready_count;
771 if (p == GNUNET_SCHEDULER_PRIORITY_KEEP) 766 if (p == GNUNET_SCHEDULER_PRIORITY_KEEP)
772 p = current_priority; 767 p = current_priority;
773 ret = 0; 768 ret = 0;
774 for (pos = ready_head[check_priority (p)]; NULL != pos; pos = pos->next) 769 for (pos = ready_head[check_priority(p)]; NULL != pos; pos = pos->next)
775 ret++; 770 ret++;
776 return ret; 771 return ret;
777} 772}
778 773
779 774
780void 775void
781init_fd_info (struct GNUNET_SCHEDULER_Task *t, 776init_fd_info(struct GNUNET_SCHEDULER_Task *t,
782 const struct GNUNET_NETWORK_Handle *const *read_nh, 777 const struct GNUNET_NETWORK_Handle *const *read_nh,
783 unsigned int read_nh_len, 778 unsigned int read_nh_len,
784 const struct GNUNET_NETWORK_Handle *const *write_nh, 779 const struct GNUNET_NETWORK_Handle *const *write_nh,
785 unsigned int write_nh_len, 780 unsigned int write_nh_len,
786 const struct GNUNET_DISK_FileHandle *const *read_fh, 781 const struct GNUNET_DISK_FileHandle *const *read_fh,
787 unsigned int read_fh_len, 782 unsigned int read_fh_len,
788 const struct GNUNET_DISK_FileHandle *const *write_fh, 783 const struct GNUNET_DISK_FileHandle *const *write_fh,
789 unsigned int write_fh_len) 784 unsigned int write_fh_len)
790{ 785{
791 // FIXME: if we have exactly two network handles / exactly two file handles 786 // FIXME: if we have exactly two network handles / exactly two file handles
792 // and they are equal, we can make one FdInfo with both 787 // and they are equal, we can make one FdInfo with both
@@ -795,90 +790,90 @@ init_fd_info (struct GNUNET_SCHEDULER_Task *t,
795 790
796 t->fds_len = read_nh_len + write_nh_len + read_fh_len + write_fh_len; 791 t->fds_len = read_nh_len + write_nh_len + read_fh_len + write_fh_len;
797 if (1 == t->fds_len) 792 if (1 == t->fds_len)
798 {
799 fdi = &t->fdx;
800 t->fds = fdi;
801 if (1 == read_nh_len)
802 { 793 {
803 GNUNET_assert (NULL != read_nh); 794 fdi = &t->fdx;
804 GNUNET_assert (NULL != *read_nh); 795 t->fds = fdi;
805 fdi->fd = *read_nh; 796 if (1 == read_nh_len)
806 fdi->et = GNUNET_SCHEDULER_ET_IN; 797 {
807 fdi->sock = GNUNET_NETWORK_get_fd (*read_nh); 798 GNUNET_assert(NULL != read_nh);
808 t->read_fd = fdi->sock; 799 GNUNET_assert(NULL != *read_nh);
809 t->write_fd = -1; 800 fdi->fd = *read_nh;
801 fdi->et = GNUNET_SCHEDULER_ET_IN;
802 fdi->sock = GNUNET_NETWORK_get_fd(*read_nh);
803 t->read_fd = fdi->sock;
804 t->write_fd = -1;
805 }
806 else if (1 == write_nh_len)
807 {
808 GNUNET_assert(NULL != write_nh);
809 GNUNET_assert(NULL != *write_nh);
810 fdi->fd = *write_nh;
811 fdi->et = GNUNET_SCHEDULER_ET_OUT;
812 fdi->sock = GNUNET_NETWORK_get_fd(*write_nh);
813 t->read_fd = -1;
814 t->write_fd = fdi->sock;
815 }
816 else if (1 == read_fh_len)
817 {
818 GNUNET_assert(NULL != read_fh);
819 GNUNET_assert(NULL != *read_fh);
820 fdi->fh = *read_fh;
821 fdi->et = GNUNET_SCHEDULER_ET_IN;
822 fdi->sock = (*read_fh)->fd; // FIXME: does not work under WIN32
823 t->read_fd = fdi->sock;
824 t->write_fd = -1;
825 }
826 else
827 {
828 GNUNET_assert(NULL != write_fh);
829 GNUNET_assert(NULL != *write_fh);
830 fdi->fh = *write_fh;
831 fdi->et = GNUNET_SCHEDULER_ET_OUT;
832 fdi->sock = (*write_fh)->fd; // FIXME: does not work under WIN32
833 t->read_fd = -1;
834 t->write_fd = fdi->sock;
835 }
810 } 836 }
811 else if (1 == write_nh_len) 837 else
812 { 838 {
813 GNUNET_assert (NULL != write_nh); 839 fdi = GNUNET_new_array(t->fds_len, struct GNUNET_SCHEDULER_FdInfo);
814 GNUNET_assert (NULL != *write_nh); 840 t->fds = fdi;
815 fdi->fd = *write_nh;
816 fdi->et = GNUNET_SCHEDULER_ET_OUT;
817 fdi->sock = GNUNET_NETWORK_get_fd (*write_nh);
818 t->read_fd = -1; 841 t->read_fd = -1;
819 t->write_fd = fdi->sock;
820 }
821 else if (1 == read_fh_len)
822 {
823 GNUNET_assert (NULL != read_fh);
824 GNUNET_assert (NULL != *read_fh);
825 fdi->fh = *read_fh;
826 fdi->et = GNUNET_SCHEDULER_ET_IN;
827 fdi->sock = (*read_fh)->fd; // FIXME: does not work under WIN32
828 t->read_fd = fdi->sock;
829 t->write_fd = -1; 842 t->write_fd = -1;
843 unsigned int i;
844 for (i = 0; i != read_nh_len; ++i)
845 {
846 fdi->fd = read_nh[i];
847 GNUNET_assert(NULL != fdi->fd);
848 fdi->et = GNUNET_SCHEDULER_ET_IN;
849 fdi->sock = GNUNET_NETWORK_get_fd(read_nh[i]);
850 ++fdi;
851 }
852 for (i = 0; i != write_nh_len; ++i)
853 {
854 fdi->fd = write_nh[i];
855 GNUNET_assert(NULL != fdi->fd);
856 fdi->et = GNUNET_SCHEDULER_ET_OUT;
857 fdi->sock = GNUNET_NETWORK_get_fd(write_nh[i]);
858 ++fdi;
859 }
860 for (i = 0; i != read_fh_len; ++i)
861 {
862 fdi->fh = read_fh[i];
863 GNUNET_assert(NULL != fdi->fh);
864 fdi->et = GNUNET_SCHEDULER_ET_IN;
865 fdi->sock = (read_fh[i])->fd; // FIXME: does not work under WIN32
866 ++fdi;
867 }
868 for (i = 0; i != write_fh_len; ++i)
869 {
870 fdi->fh = write_fh[i];
871 GNUNET_assert(NULL != fdi->fh);
872 fdi->et = GNUNET_SCHEDULER_ET_OUT;
873 fdi->sock = (write_fh[i])->fd; // FIXME: does not work under WIN32
874 ++fdi;
875 }
830 } 876 }
831 else
832 {
833 GNUNET_assert (NULL != write_fh);
834 GNUNET_assert (NULL != *write_fh);
835 fdi->fh = *write_fh;
836 fdi->et = GNUNET_SCHEDULER_ET_OUT;
837 fdi->sock = (*write_fh)->fd; // FIXME: does not work under WIN32
838 t->read_fd = -1;
839 t->write_fd = fdi->sock;
840 }
841 }
842 else
843 {
844 fdi = GNUNET_new_array (t->fds_len, struct GNUNET_SCHEDULER_FdInfo);
845 t->fds = fdi;
846 t->read_fd = -1;
847 t->write_fd = -1;
848 unsigned int i;
849 for (i = 0; i != read_nh_len; ++i)
850 {
851 fdi->fd = read_nh[i];
852 GNUNET_assert (NULL != fdi->fd);
853 fdi->et = GNUNET_SCHEDULER_ET_IN;
854 fdi->sock = GNUNET_NETWORK_get_fd (read_nh[i]);
855 ++fdi;
856 }
857 for (i = 0; i != write_nh_len; ++i)
858 {
859 fdi->fd = write_nh[i];
860 GNUNET_assert (NULL != fdi->fd);
861 fdi->et = GNUNET_SCHEDULER_ET_OUT;
862 fdi->sock = GNUNET_NETWORK_get_fd (write_nh[i]);
863 ++fdi;
864 }
865 for (i = 0; i != read_fh_len; ++i)
866 {
867 fdi->fh = read_fh[i];
868 GNUNET_assert (NULL != fdi->fh);
869 fdi->et = GNUNET_SCHEDULER_ET_IN;
870 fdi->sock = (read_fh[i])->fd; // FIXME: does not work under WIN32
871 ++fdi;
872 }
873 for (i = 0; i != write_fh_len; ++i)
874 {
875 fdi->fh = write_fh[i];
876 GNUNET_assert (NULL != fdi->fh);
877 fdi->et = GNUNET_SCHEDULER_ET_OUT;
878 fdi->sock = (write_fh[i])->fd; // FIXME: does not work under WIN32
879 ++fdi;
880 }
881 }
882} 877}
883 878
884 879
@@ -896,56 +891,56 @@ init_fd_info (struct GNUNET_SCHEDULER_Task *t,
896 * @a driver_func on it, or -1 if no updating not desired. 891 * @a driver_func on it, or -1 if no updating not desired.
897 */ 892 */
898static void 893static void
899driver_add_multiple (struct GNUNET_SCHEDULER_Task *t) 894driver_add_multiple(struct GNUNET_SCHEDULER_Task *t)
900{ 895{
901 struct GNUNET_SCHEDULER_FdInfo *fdi; 896 struct GNUNET_SCHEDULER_FdInfo *fdi;
902 int success = GNUNET_YES; 897 int success = GNUNET_YES;
903 898
904 for (unsigned int i = 0; i != t->fds_len; ++i) 899 for (unsigned int i = 0; i != t->fds_len; ++i)
905 { 900 {
906 fdi = &t->fds[i]; 901 fdi = &t->fds[i];
907 success = scheduler_driver->add (scheduler_driver->cls, 902 success = scheduler_driver->add(scheduler_driver->cls,
908 t, 903 t,
909 fdi) && success; 904 fdi) && success;
910 fdi->et = GNUNET_SCHEDULER_ET_NONE; 905 fdi->et = GNUNET_SCHEDULER_ET_NONE;
911 } 906 }
912 if (GNUNET_YES != success) 907 if (GNUNET_YES != success)
913 { 908 {
914 LOG (GNUNET_ERROR_TYPE_ERROR, 909 LOG(GNUNET_ERROR_TYPE_ERROR,
915 "driver could not add task\n"); 910 "driver could not add task\n");
916 } 911 }
917} 912}
918 913
919 914
920static void 915static void
921install_parent_control_handler (void *cls) 916install_parent_control_handler(void *cls)
922{ 917{
923 (void) cls; 918 (void)cls;
924 install_parent_control_task = NULL; 919 install_parent_control_task = NULL;
925 GNUNET_OS_install_parent_control_handler (NULL); 920 GNUNET_OS_install_parent_control_handler(NULL);
926} 921}
927 922
928 923
929static void 924static void
930shutdown_pipe_cb (void *cls) 925shutdown_pipe_cb(void *cls)
931{ 926{
932 char c; 927 char c;
933 const struct GNUNET_DISK_FileHandle *pr; 928 const struct GNUNET_DISK_FileHandle *pr;
934 929
935 (void) cls; 930 (void)cls;
936 shutdown_pipe_task = NULL; 931 shutdown_pipe_task = NULL;
937 pr = GNUNET_DISK_pipe_handle (shutdown_pipe_handle, 932 pr = GNUNET_DISK_pipe_handle(shutdown_pipe_handle,
938 GNUNET_DISK_PIPE_END_READ); 933 GNUNET_DISK_PIPE_END_READ);
939 GNUNET_assert (! GNUNET_DISK_handle_invalid (pr)); 934 GNUNET_assert(!GNUNET_DISK_handle_invalid(pr));
940 /* consume the signal */ 935 /* consume the signal */
941 GNUNET_DISK_file_read (pr, &c, sizeof (c)); 936 GNUNET_DISK_file_read(pr, &c, sizeof(c));
942 /* mark all active tasks as ready due to shutdown */ 937 /* mark all active tasks as ready due to shutdown */
943 GNUNET_SCHEDULER_shutdown (); 938 GNUNET_SCHEDULER_shutdown();
944 shutdown_pipe_task = 939 shutdown_pipe_task =
945 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 940 GNUNET_SCHEDULER_add_read_file(GNUNET_TIME_UNIT_FOREVER_REL,
946 pr, 941 pr,
947 &shutdown_pipe_cb, 942 &shutdown_pipe_cb,
948 NULL); 943 NULL);
949} 944}
950 945
951 946
@@ -962,62 +957,62 @@ shutdown_pipe_cb (void *cls)
962 * @return original closure of the task 957 * @return original closure of the task
963 */ 958 */
964void * 959void *
965GNUNET_SCHEDULER_cancel (struct GNUNET_SCHEDULER_Task *task) 960GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
966{ 961{
967 enum GNUNET_SCHEDULER_Priority p; 962 enum GNUNET_SCHEDULER_Priority p;
968 int is_fd_task; 963 int is_fd_task;
969 void *ret; 964 void *ret;
970 965
971 LOG (GNUNET_ERROR_TYPE_DEBUG, 966 LOG(GNUNET_ERROR_TYPE_DEBUG,
972 "canceling task %p\n", 967 "canceling task %p\n",
973 task); 968 task);
974 969
975 /* scheduler must be running */ 970 /* scheduler must be running */
976 GNUNET_assert (NULL != scheduler_driver); 971 GNUNET_assert(NULL != scheduler_driver);
977 is_fd_task = (NULL != task->fds); 972 is_fd_task = (NULL != task->fds);
978 if (is_fd_task) 973 if (is_fd_task)
979 {
980 int del_result = scheduler_driver->del (scheduler_driver->cls, task);
981 if (GNUNET_OK != del_result)
982 {
983 LOG (GNUNET_ERROR_TYPE_ERROR,
984 "driver could not delete task\n");
985 GNUNET_assert (0);
986 }
987 }
988 if (! task->in_ready_list)
989 {
990 if (is_fd_task)
991 { 974 {
992 GNUNET_CONTAINER_DLL_remove (pending_head, 975 int del_result = scheduler_driver->del(scheduler_driver->cls, task);
993 pending_tail, 976 if (GNUNET_OK != del_result)
994 task); 977 {
978 LOG(GNUNET_ERROR_TYPE_ERROR,
979 "driver could not delete task\n");
980 GNUNET_assert(0);
981 }
995 } 982 }
996 else if (GNUNET_YES == task->on_shutdown) 983 if (!task->in_ready_list)
997 { 984 {
998 GNUNET_CONTAINER_DLL_remove (shutdown_head, 985 if (is_fd_task)
999 shutdown_tail, 986 {
1000 task); 987 GNUNET_CONTAINER_DLL_remove(pending_head,
988 pending_tail,
989 task);
990 }
991 else if (GNUNET_YES == task->on_shutdown)
992 {
993 GNUNET_CONTAINER_DLL_remove(shutdown_head,
994 shutdown_tail,
995 task);
996 }
997 else
998 {
999 GNUNET_CONTAINER_DLL_remove(pending_timeout_head,
1000 pending_timeout_tail,
1001 task);
1002 if (pending_timeout_last == task)
1003 pending_timeout_last = NULL;
1004 }
1001 } 1005 }
1002 else 1006 else
1003 { 1007 {
1004 GNUNET_CONTAINER_DLL_remove (pending_timeout_head, 1008 p = check_priority(task->priority);
1005 pending_timeout_tail, 1009 GNUNET_CONTAINER_DLL_remove(ready_head[p],
1006 task); 1010 ready_tail[p],
1007 if (pending_timeout_last == task) 1011 task);
1008 pending_timeout_last = NULL; 1012 ready_count--;
1009 } 1013 }
1010 }
1011 else
1012 {
1013 p = check_priority (task->priority);
1014 GNUNET_CONTAINER_DLL_remove (ready_head[p],
1015 ready_tail[p],
1016 task);
1017 ready_count--;
1018 }
1019 ret = task->callback_cls; 1014 ret = task->callback_cls;
1020 destroy_task (task); 1015 destroy_task(task);
1021 return ret; 1016 return ret;
1022} 1017}
1023 1018
@@ -1028,19 +1023,19 @@ GNUNET_SCHEDULER_cancel (struct GNUNET_SCHEDULER_Task *task)
1028 * @param t task to initialize 1023 * @param t task to initialize
1029 */ 1024 */
1030static void 1025static void
1031init_backtrace (struct GNUNET_SCHEDULER_Task *t) 1026init_backtrace(struct GNUNET_SCHEDULER_Task *t)
1032{ 1027{
1033#if EXECINFO 1028#if EXECINFO
1034 void *backtrace_array[MAX_TRACE_DEPTH]; 1029 void *backtrace_array[MAX_TRACE_DEPTH];
1035 1030
1036 t->num_backtrace_strings 1031 t->num_backtrace_strings
1037 = backtrace (backtrace_array, MAX_TRACE_DEPTH); 1032 = backtrace(backtrace_array, MAX_TRACE_DEPTH);
1038 t->backtrace_strings = 1033 t->backtrace_strings =
1039 backtrace_symbols (backtrace_array, 1034 backtrace_symbols(backtrace_array,
1040 t->num_backtrace_strings); 1035 t->num_backtrace_strings);
1041 dump_backtrace (t); 1036 dump_backtrace(t);
1042#else 1037#else
1043 (void) t; 1038 (void)t;
1044#endif 1039#endif
1045} 1040}
1046 1041
@@ -1056,32 +1051,32 @@ init_backtrace (struct GNUNET_SCHEDULER_Task *t)
1056 * @param priority priority to use for the task 1051 * @param priority priority to use for the task
1057 */ 1052 */
1058void 1053void
1059GNUNET_SCHEDULER_add_with_reason_and_priority (GNUNET_SCHEDULER_TaskCallback task, 1054GNUNET_SCHEDULER_add_with_reason_and_priority(GNUNET_SCHEDULER_TaskCallback task,
1060 void *task_cls, 1055 void *task_cls,
1061 enum GNUNET_SCHEDULER_Reason reason, 1056 enum GNUNET_SCHEDULER_Reason reason,
1062 enum GNUNET_SCHEDULER_Priority priority) 1057 enum GNUNET_SCHEDULER_Priority priority)
1063{ 1058{
1064 struct GNUNET_SCHEDULER_Task *t; 1059 struct GNUNET_SCHEDULER_Task *t;
1065 1060
1066 /* scheduler must be running */ 1061 /* scheduler must be running */
1067 GNUNET_assert (NULL != scheduler_driver); 1062 GNUNET_assert(NULL != scheduler_driver);
1068 GNUNET_assert (NULL != task); 1063 GNUNET_assert(NULL != task);
1069 t = GNUNET_new (struct GNUNET_SCHEDULER_Task); 1064 t = GNUNET_new(struct GNUNET_SCHEDULER_Task);
1070 t->read_fd = -1; 1065 t->read_fd = -1;
1071 t->write_fd = -1; 1066 t->write_fd = -1;
1072 t->callback = task; 1067 t->callback = task;
1073 t->callback_cls = task_cls; 1068 t->callback_cls = task_cls;
1074#if PROFILE_DELAYS 1069#if PROFILE_DELAYS
1075 t->start_time = GNUNET_TIME_absolute_get (); 1070 t->start_time = GNUNET_TIME_absolute_get();
1076#endif 1071#endif
1077 t->reason = reason; 1072 t->reason = reason;
1078 t->priority = check_priority (priority); 1073 t->priority = check_priority(priority);
1079 t->lifeness = current_lifeness; 1074 t->lifeness = current_lifeness;
1080 LOG (GNUNET_ERROR_TYPE_DEBUG, 1075 LOG(GNUNET_ERROR_TYPE_DEBUG,
1081 "Adding continuation task %p\n", 1076 "Adding continuation task %p\n",
1082 t); 1077 t);
1083 init_backtrace (t); 1078 init_backtrace(t);
1084 queue_ready_task (t); 1079 queue_ready_task(t);
1085} 1080}
1086 1081
1087 1082
@@ -1097,68 +1092,68 @@ GNUNET_SCHEDULER_add_with_reason_and_priority (GNUNET_SCHEDULER_TaskCallback tas
1097 * only valid until @a task is started! 1092 * only valid until @a task is started!
1098 */ 1093 */
1099struct GNUNET_SCHEDULER_Task * 1094struct GNUNET_SCHEDULER_Task *
1100GNUNET_SCHEDULER_add_at_with_priority (struct GNUNET_TIME_Absolute at, 1095GNUNET_SCHEDULER_add_at_with_priority(struct GNUNET_TIME_Absolute at,
1101 enum GNUNET_SCHEDULER_Priority priority, 1096 enum GNUNET_SCHEDULER_Priority priority,
1102 GNUNET_SCHEDULER_TaskCallback task, 1097 GNUNET_SCHEDULER_TaskCallback task,
1103 void *task_cls) 1098 void *task_cls)
1104{ 1099{
1105 struct GNUNET_SCHEDULER_Task *t; 1100 struct GNUNET_SCHEDULER_Task *t;
1106 struct GNUNET_SCHEDULER_Task *pos; 1101 struct GNUNET_SCHEDULER_Task *pos;
1107 struct GNUNET_SCHEDULER_Task *prev; 1102 struct GNUNET_SCHEDULER_Task *prev;
1108 1103
1109 /* scheduler must be running */ 1104 /* scheduler must be running */
1110 GNUNET_assert (NULL != scheduler_driver); 1105 GNUNET_assert(NULL != scheduler_driver);
1111 GNUNET_assert (NULL != task); 1106 GNUNET_assert(NULL != task);
1112 t = GNUNET_new (struct GNUNET_SCHEDULER_Task); 1107 t = GNUNET_new(struct GNUNET_SCHEDULER_Task);
1113 GNUNET_async_scope_get (&t->scope); 1108 GNUNET_async_scope_get(&t->scope);
1114 t->callback = task; 1109 t->callback = task;
1115 t->callback_cls = task_cls; 1110 t->callback_cls = task_cls;
1116 t->read_fd = -1; 1111 t->read_fd = -1;
1117 t->write_fd = -1; 1112 t->write_fd = -1;
1118#if PROFILE_DELAYS 1113#if PROFILE_DELAYS
1119 t->start_time = GNUNET_TIME_absolute_get (); 1114 t->start_time = GNUNET_TIME_absolute_get();
1120#endif 1115#endif
1121 t->timeout = at; 1116 t->timeout = at;
1122 t->priority = check_priority (priority); 1117 t->priority = check_priority(priority);
1123 t->lifeness = current_lifeness; 1118 t->lifeness = current_lifeness;
1124 /* try tail first (optimization in case we are 1119 /* try tail first (optimization in case we are
1125 * appending to a long list of tasks with timeouts) */ 1120 * appending to a long list of tasks with timeouts) */
1126 if ( (NULL == pending_timeout_head) || 1121 if ((NULL == pending_timeout_head) ||
1127 (at.abs_value_us < pending_timeout_head->timeout.abs_value_us) ) 1122 (at.abs_value_us < pending_timeout_head->timeout.abs_value_us))
1128 { 1123 {
1129 GNUNET_CONTAINER_DLL_insert (pending_timeout_head, 1124 GNUNET_CONTAINER_DLL_insert(pending_timeout_head,
1130 pending_timeout_tail, 1125 pending_timeout_tail,
1131 t); 1126 t);
1132 } 1127 }
1133 else 1128 else
1134 {
1135 /* first move from heuristic start backwards to before start time */
1136 prev = pending_timeout_last;
1137 while ( (NULL != prev) &&
1138 (prev->timeout.abs_value_us > t->timeout.abs_value_us) )
1139 prev = prev->prev;
1140 /* now, move from heuristic start (or head of list) forward to insertion point */
1141 if (NULL == prev)
1142 pos = pending_timeout_head;
1143 else
1144 pos = prev->next;
1145 while ((NULL != pos) && (pos->timeout.abs_value_us <= t->timeout.abs_value_us))
1146 { 1129 {
1147 prev = pos; 1130 /* first move from heuristic start backwards to before start time */
1148 pos = pos->next; 1131 prev = pending_timeout_last;
1132 while ((NULL != prev) &&
1133 (prev->timeout.abs_value_us > t->timeout.abs_value_us))
1134 prev = prev->prev;
1135 /* now, move from heuristic start (or head of list) forward to insertion point */
1136 if (NULL == prev)
1137 pos = pending_timeout_head;
1138 else
1139 pos = prev->next;
1140 while ((NULL != pos) && (pos->timeout.abs_value_us <= t->timeout.abs_value_us))
1141 {
1142 prev = pos;
1143 pos = pos->next;
1144 }
1145 GNUNET_CONTAINER_DLL_insert_after(pending_timeout_head,
1146 pending_timeout_tail,
1147 prev,
1148 t);
1149 } 1149 }
1150 GNUNET_CONTAINER_DLL_insert_after (pending_timeout_head,
1151 pending_timeout_tail,
1152 prev,
1153 t);
1154 }
1155 /* finally, update heuristic insertion point to last insertion... */ 1150 /* finally, update heuristic insertion point to last insertion... */
1156 pending_timeout_last = t; 1151 pending_timeout_last = t;
1157 1152
1158 LOG (GNUNET_ERROR_TYPE_DEBUG, 1153 LOG(GNUNET_ERROR_TYPE_DEBUG,
1159 "Adding task %p\n", 1154 "Adding task %p\n",
1160 t); 1155 t);
1161 init_backtrace (t); 1156 init_backtrace(t);
1162 return t; 1157 return t;
1163} 1158}
1164 1159
@@ -1175,15 +1170,15 @@ GNUNET_SCHEDULER_add_at_with_priority (struct GNUNET_TIME_Absolute at,
1175 * only valid until @a task is started! 1170 * only valid until @a task is started!
1176 */ 1171 */
1177struct GNUNET_SCHEDULER_Task * 1172struct GNUNET_SCHEDULER_Task *
1178GNUNET_SCHEDULER_add_delayed_with_priority (struct GNUNET_TIME_Relative delay, 1173GNUNET_SCHEDULER_add_delayed_with_priority(struct GNUNET_TIME_Relative delay,
1179 enum GNUNET_SCHEDULER_Priority priority, 1174 enum GNUNET_SCHEDULER_Priority priority,
1180 GNUNET_SCHEDULER_TaskCallback task, 1175 GNUNET_SCHEDULER_TaskCallback task,
1181 void *task_cls) 1176 void *task_cls)
1182{ 1177{
1183 return GNUNET_SCHEDULER_add_at_with_priority (GNUNET_TIME_relative_to_absolute (delay), 1178 return GNUNET_SCHEDULER_add_at_with_priority(GNUNET_TIME_relative_to_absolute(delay),
1184 priority, 1179 priority,
1185 task, 1180 task,
1186 task_cls); 1181 task_cls);
1187} 1182}
1188 1183
1189 1184
@@ -1197,14 +1192,14 @@ GNUNET_SCHEDULER_add_delayed_with_priority (struct GNUNET_TIME_Relative delay,
1197 * only valid until @a task is started! 1192 * only valid until @a task is started!
1198 */ 1193 */
1199struct GNUNET_SCHEDULER_Task * 1194struct GNUNET_SCHEDULER_Task *
1200GNUNET_SCHEDULER_add_with_priority (enum GNUNET_SCHEDULER_Priority prio, 1195GNUNET_SCHEDULER_add_with_priority(enum GNUNET_SCHEDULER_Priority prio,
1201 GNUNET_SCHEDULER_TaskCallback task, 1196 GNUNET_SCHEDULER_TaskCallback task,
1202 void *task_cls) 1197 void *task_cls)
1203{ 1198{
1204 return GNUNET_SCHEDULER_add_delayed_with_priority (GNUNET_TIME_UNIT_ZERO, 1199 return GNUNET_SCHEDULER_add_delayed_with_priority(GNUNET_TIME_UNIT_ZERO,
1205 prio, 1200 prio,
1206 task, 1201 task,
1207 task_cls); 1202 task_cls);
1208} 1203}
1209 1204
1210 1205
@@ -1220,14 +1215,14 @@ GNUNET_SCHEDULER_add_with_priority (enum GNUNET_SCHEDULER_Priority prio,
1220 * only valid until @a task is started! 1215 * only valid until @a task is started!
1221 */ 1216 */
1222struct GNUNET_SCHEDULER_Task * 1217struct GNUNET_SCHEDULER_Task *
1223GNUNET_SCHEDULER_add_at (struct GNUNET_TIME_Absolute at, 1218GNUNET_SCHEDULER_add_at(struct GNUNET_TIME_Absolute at,
1224 GNUNET_SCHEDULER_TaskCallback task, 1219 GNUNET_SCHEDULER_TaskCallback task,
1225 void *task_cls) 1220 void *task_cls)
1226{ 1221{
1227 return GNUNET_SCHEDULER_add_at_with_priority (at, 1222 return GNUNET_SCHEDULER_add_at_with_priority(at,
1228 GNUNET_SCHEDULER_PRIORITY_DEFAULT, 1223 GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1229 task, 1224 task,
1230 task_cls); 1225 task_cls);
1231} 1226}
1232 1227
1233 1228
@@ -1243,14 +1238,14 @@ GNUNET_SCHEDULER_add_at (struct GNUNET_TIME_Absolute at,
1243 * only valid until @a task is started! 1238 * only valid until @a task is started!
1244 */ 1239 */
1245struct GNUNET_SCHEDULER_Task * 1240struct GNUNET_SCHEDULER_Task *
1246GNUNET_SCHEDULER_add_delayed (struct GNUNET_TIME_Relative delay, 1241GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay,
1247 GNUNET_SCHEDULER_TaskCallback task, 1242 GNUNET_SCHEDULER_TaskCallback task,
1248 void *task_cls) 1243 void *task_cls)
1249{ 1244{
1250 return GNUNET_SCHEDULER_add_delayed_with_priority (delay, 1245 return GNUNET_SCHEDULER_add_delayed_with_priority(delay,
1251 GNUNET_SCHEDULER_PRIORITY_DEFAULT, 1246 GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1252 task, 1247 task,
1253 task_cls); 1248 task_cls);
1254} 1249}
1255 1250
1256 1251
@@ -1270,12 +1265,12 @@ GNUNET_SCHEDULER_add_delayed (struct GNUNET_TIME_Relative delay,
1270 * only valid until @a task is started! 1265 * only valid until @a task is started!
1271 */ 1266 */
1272struct GNUNET_SCHEDULER_Task * 1267struct GNUNET_SCHEDULER_Task *
1273GNUNET_SCHEDULER_add_now (GNUNET_SCHEDULER_TaskCallback task, 1268GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task,
1274 void *task_cls) 1269 void *task_cls)
1275{ 1270{
1276 return GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_ZERO, 1271 return GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_UNIT_ZERO,
1277 task, 1272 task,
1278 task_cls); 1273 task_cls);
1279} 1274}
1280 1275
1281 1276
@@ -1290,34 +1285,34 @@ GNUNET_SCHEDULER_add_now (GNUNET_SCHEDULER_TaskCallback task,
1290 * only valid until @a task is started! 1285 * only valid until @a task is started!
1291 */ 1286 */
1292struct GNUNET_SCHEDULER_Task * 1287struct GNUNET_SCHEDULER_Task *
1293GNUNET_SCHEDULER_add_shutdown (GNUNET_SCHEDULER_TaskCallback task, 1288GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task,
1294 void *task_cls) 1289 void *task_cls)
1295{ 1290{
1296 struct GNUNET_SCHEDULER_Task *t; 1291 struct GNUNET_SCHEDULER_Task *t;
1297 1292
1298 /* scheduler must be running */ 1293 /* scheduler must be running */
1299 GNUNET_assert (NULL != scheduler_driver); 1294 GNUNET_assert(NULL != scheduler_driver);
1300 GNUNET_assert (NULL != task); 1295 GNUNET_assert(NULL != task);
1301 t = GNUNET_new (struct GNUNET_SCHEDULER_Task); 1296 t = GNUNET_new(struct GNUNET_SCHEDULER_Task);
1302 GNUNET_async_scope_get (&t->scope); 1297 GNUNET_async_scope_get(&t->scope);
1303 t->callback = task; 1298 t->callback = task;
1304 t->callback_cls = task_cls; 1299 t->callback_cls = task_cls;
1305 t->read_fd = -1; 1300 t->read_fd = -1;
1306 t->write_fd = -1; 1301 t->write_fd = -1;
1307#if PROFILE_DELAYS 1302#if PROFILE_DELAYS
1308 t->start_time = GNUNET_TIME_absolute_get (); 1303 t->start_time = GNUNET_TIME_absolute_get();
1309#endif 1304#endif
1310 t->timeout = GNUNET_TIME_UNIT_FOREVER_ABS; 1305 t->timeout = GNUNET_TIME_UNIT_FOREVER_ABS;
1311 t->priority = GNUNET_SCHEDULER_PRIORITY_SHUTDOWN; 1306 t->priority = GNUNET_SCHEDULER_PRIORITY_SHUTDOWN;
1312 t->on_shutdown = GNUNET_YES; 1307 t->on_shutdown = GNUNET_YES;
1313 t->lifeness = GNUNET_NO; 1308 t->lifeness = GNUNET_NO;
1314 GNUNET_CONTAINER_DLL_insert (shutdown_head, 1309 GNUNET_CONTAINER_DLL_insert(shutdown_head,
1315 shutdown_tail, 1310 shutdown_tail,
1316 t); 1311 t);
1317 LOG (GNUNET_ERROR_TYPE_DEBUG, 1312 LOG(GNUNET_ERROR_TYPE_DEBUG,
1318 "Adding shutdown task %p\n", 1313 "Adding shutdown task %p\n",
1319 t); 1314 t);
1320 init_backtrace (t); 1315 init_backtrace(t);
1321 return t; 1316 return t;
1322} 1317}
1323 1318
@@ -1337,13 +1332,13 @@ GNUNET_SCHEDULER_add_shutdown (GNUNET_SCHEDULER_TaskCallback task,
1337 * only valid until @a task is started! 1332 * only valid until @a task is started!
1338 */ 1333 */
1339struct GNUNET_SCHEDULER_Task * 1334struct GNUNET_SCHEDULER_Task *
1340GNUNET_SCHEDULER_add_now_with_lifeness (int lifeness, 1335GNUNET_SCHEDULER_add_now_with_lifeness(int lifeness,
1341 GNUNET_SCHEDULER_TaskCallback task, 1336 GNUNET_SCHEDULER_TaskCallback task,
1342 void *task_cls) 1337 void *task_cls)
1343{ 1338{
1344 struct GNUNET_SCHEDULER_Task *ret; 1339 struct GNUNET_SCHEDULER_Task *ret;
1345 1340
1346 ret = GNUNET_SCHEDULER_add_now (task, task_cls); 1341 ret = GNUNET_SCHEDULER_add_now(task, task_cls);
1347 ret->lifeness = lifeness; 1342 ret->lifeness = lifeness;
1348 return ret; 1343 return ret;
1349} 1344}
@@ -1357,21 +1352,21 @@ GNUNET_SCHEDULER_add_now_with_lifeness (int lifeness,
1357 * @param raw_fd the raw file descriptor to check 1352 * @param raw_fd the raw file descriptor to check
1358 */ 1353 */
1359void 1354void
1360check_fd (struct GNUNET_SCHEDULER_Task *t, int raw_fd) 1355check_fd(struct GNUNET_SCHEDULER_Task *t, int raw_fd)
1361{ 1356{
1362 if (-1 != raw_fd) 1357 if (-1 != raw_fd)
1363 {
1364 int flags = fcntl (raw_fd, F_GETFD);
1365
1366 if ((flags == -1) && (errno == EBADF))
1367 { 1358 {
1368 LOG (GNUNET_ERROR_TYPE_ERROR, 1359 int flags = fcntl(raw_fd, F_GETFD);
1369 "Got invalid file descriptor %d!\n", 1360
1370 raw_fd); 1361 if ((flags == -1) && (errno == EBADF))
1371 init_backtrace (t); 1362 {
1372 GNUNET_assert (0); 1363 LOG(GNUNET_ERROR_TYPE_ERROR,
1364 "Got invalid file descriptor %d!\n",
1365 raw_fd);
1366 init_backtrace(t);
1367 GNUNET_assert(0);
1368 }
1373 } 1369 }
1374 }
1375} 1370}
1376#endif 1371#endif
1377 1372
@@ -1403,52 +1398,52 @@ check_fd (struct GNUNET_SCHEDULER_Task *t, int raw_fd)
1403 */ 1398 */
1404#ifndef MINGW 1399#ifndef MINGW
1405static struct GNUNET_SCHEDULER_Task * 1400static struct GNUNET_SCHEDULER_Task *
1406add_without_sets (struct GNUNET_TIME_Relative delay, 1401add_without_sets(struct GNUNET_TIME_Relative delay,
1407 enum GNUNET_SCHEDULER_Priority priority, 1402 enum GNUNET_SCHEDULER_Priority priority,
1408 const struct GNUNET_NETWORK_Handle *read_nh, 1403 const struct GNUNET_NETWORK_Handle *read_nh,
1409 const struct GNUNET_NETWORK_Handle *write_nh, 1404 const struct GNUNET_NETWORK_Handle *write_nh,
1410 const struct GNUNET_DISK_FileHandle *read_fh, 1405 const struct GNUNET_DISK_FileHandle *read_fh,
1411 const struct GNUNET_DISK_FileHandle *write_fh, 1406 const struct GNUNET_DISK_FileHandle *write_fh,
1412 GNUNET_SCHEDULER_TaskCallback task, 1407 GNUNET_SCHEDULER_TaskCallback task,
1413 void *task_cls) 1408 void *task_cls)
1414{ 1409{
1415 struct GNUNET_SCHEDULER_Task *t; 1410 struct GNUNET_SCHEDULER_Task *t;
1416 1411
1417 /* scheduler must be running */ 1412 /* scheduler must be running */
1418 GNUNET_assert (NULL != scheduler_driver); 1413 GNUNET_assert(NULL != scheduler_driver);
1419 GNUNET_assert (NULL != task); 1414 GNUNET_assert(NULL != task);
1420 t = GNUNET_new (struct GNUNET_SCHEDULER_Task); 1415 t = GNUNET_new(struct GNUNET_SCHEDULER_Task);
1421 GNUNET_async_scope_get (&t->scope); 1416 GNUNET_async_scope_get(&t->scope);
1422 init_fd_info (t, 1417 init_fd_info(t,
1423 &read_nh, 1418 &read_nh,
1424 read_nh ? 1 : 0, 1419 read_nh ? 1 : 0,
1425 &write_nh, 1420 &write_nh,
1426 write_nh ? 1 : 0, 1421 write_nh ? 1 : 0,
1427 &read_fh, 1422 &read_fh,
1428 read_fh ? 1 : 0, 1423 read_fh ? 1 : 0,
1429 &write_fh, 1424 &write_fh,
1430 write_fh ? 1 : 0); 1425 write_fh ? 1 : 0);
1431 t->callback = task; 1426 t->callback = task;
1432 t->callback_cls = task_cls; 1427 t->callback_cls = task_cls;
1433#if DEBUG_FDS 1428#if DEBUG_FDS
1434 check_fd (t, NULL != read_nh ? GNUNET_NETWORK_get_fd (read_nh) : -1); 1429 check_fd(t, NULL != read_nh ? GNUNET_NETWORK_get_fd(read_nh) : -1);
1435 check_fd (t, NULL != write_nh ? GNUNET_NETWORK_get_fd (write_nh) : -1); 1430 check_fd(t, NULL != write_nh ? GNUNET_NETWORK_get_fd(write_nh) : -1);
1436 check_fd (t, NULL != read_fh ? read_fh->fd : -1); 1431 check_fd(t, NULL != read_fh ? read_fh->fd : -1);
1437 check_fd (t, NULL != write_fh ? write_fh->fd : -1); 1432 check_fd(t, NULL != write_fh ? write_fh->fd : -1);
1438#endif 1433#endif
1439#if PROFILE_DELAYS 1434#if PROFILE_DELAYS
1440 t->start_time = GNUNET_TIME_absolute_get (); 1435 t->start_time = GNUNET_TIME_absolute_get();
1441#endif 1436#endif
1442 t->timeout = GNUNET_TIME_relative_to_absolute (delay); 1437 t->timeout = GNUNET_TIME_relative_to_absolute(delay);
1443 t->priority = check_priority ((priority == GNUNET_SCHEDULER_PRIORITY_KEEP) ? current_priority : priority); 1438 t->priority = check_priority((priority == GNUNET_SCHEDULER_PRIORITY_KEEP) ? current_priority : priority);
1444 t->lifeness = current_lifeness; 1439 t->lifeness = current_lifeness;
1445 GNUNET_CONTAINER_DLL_insert (pending_head, 1440 GNUNET_CONTAINER_DLL_insert(pending_head,
1446 pending_tail, 1441 pending_tail,
1447 t); 1442 t);
1448 driver_add_multiple (t); 1443 driver_add_multiple(t);
1449 max_priority_added = GNUNET_MAX (max_priority_added, 1444 max_priority_added = GNUNET_MAX(max_priority_added,
1450 t->priority); 1445 t->priority);
1451 init_backtrace (t); 1446 init_backtrace(t);
1452 return t; 1447 return t;
1453} 1448}
1454#endif 1449#endif
@@ -1475,14 +1470,14 @@ add_without_sets (struct GNUNET_TIME_Relative delay,
1475 * only valid until @a task is started! 1470 * only valid until @a task is started!
1476 */ 1471 */
1477struct GNUNET_SCHEDULER_Task * 1472struct GNUNET_SCHEDULER_Task *
1478GNUNET_SCHEDULER_add_read_net (struct GNUNET_TIME_Relative delay, 1473GNUNET_SCHEDULER_add_read_net(struct GNUNET_TIME_Relative delay,
1479 struct GNUNET_NETWORK_Handle *rfd, 1474 struct GNUNET_NETWORK_Handle *rfd,
1480 GNUNET_SCHEDULER_TaskCallback task, 1475 GNUNET_SCHEDULER_TaskCallback task,
1481 void *task_cls) 1476 void *task_cls)
1482{ 1477{
1483 return GNUNET_SCHEDULER_add_read_net_with_priority (delay, 1478 return GNUNET_SCHEDULER_add_read_net_with_priority(delay,
1484 GNUNET_SCHEDULER_PRIORITY_DEFAULT, 1479 GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1485 rfd, task, task_cls); 1480 rfd, task, task_cls);
1486} 1481}
1487 1482
1488 1483
@@ -1509,17 +1504,17 @@ GNUNET_SCHEDULER_add_read_net (struct GNUNET_TIME_Relative delay,
1509 * only valid until @a task is started! 1504 * only valid until @a task is started!
1510 */ 1505 */
1511struct GNUNET_SCHEDULER_Task * 1506struct GNUNET_SCHEDULER_Task *
1512GNUNET_SCHEDULER_add_read_net_with_priority (struct GNUNET_TIME_Relative delay, 1507GNUNET_SCHEDULER_add_read_net_with_priority(struct GNUNET_TIME_Relative delay,
1513 enum GNUNET_SCHEDULER_Priority priority, 1508 enum GNUNET_SCHEDULER_Priority priority,
1514 struct GNUNET_NETWORK_Handle *rfd, 1509 struct GNUNET_NETWORK_Handle *rfd,
1515 GNUNET_SCHEDULER_TaskCallback task, 1510 GNUNET_SCHEDULER_TaskCallback task,
1516 void *task_cls) 1511 void *task_cls)
1517{ 1512{
1518 return GNUNET_SCHEDULER_add_net_with_priority (delay, priority, 1513 return GNUNET_SCHEDULER_add_net_with_priority(delay, priority,
1519 rfd, 1514 rfd,
1520 GNUNET_YES, 1515 GNUNET_YES,
1521 GNUNET_NO, 1516 GNUNET_NO,
1522 task, task_cls); 1517 task, task_cls);
1523} 1518}
1524 1519
1525 1520
@@ -1545,16 +1540,16 @@ GNUNET_SCHEDULER_add_read_net_with_priority (struct GNUNET_TIME_Relative delay,
1545 * only valid until @a task is started! 1540 * only valid until @a task is started!
1546 */ 1541 */
1547struct GNUNET_SCHEDULER_Task * 1542struct GNUNET_SCHEDULER_Task *
1548GNUNET_SCHEDULER_add_write_net (struct GNUNET_TIME_Relative delay, 1543GNUNET_SCHEDULER_add_write_net(struct GNUNET_TIME_Relative delay,
1549 struct GNUNET_NETWORK_Handle *wfd, 1544 struct GNUNET_NETWORK_Handle *wfd,
1550 GNUNET_SCHEDULER_TaskCallback task, 1545 GNUNET_SCHEDULER_TaskCallback task,
1551 void *task_cls) 1546 void *task_cls)
1552{ 1547{
1553 return GNUNET_SCHEDULER_add_net_with_priority (delay, 1548 return GNUNET_SCHEDULER_add_net_with_priority(delay,
1554 GNUNET_SCHEDULER_PRIORITY_DEFAULT, 1549 GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1555 wfd, 1550 wfd,
1556 GNUNET_NO, GNUNET_YES, 1551 GNUNET_NO, GNUNET_YES,
1557 task, task_cls); 1552 task, task_cls);
1558} 1553}
1559 1554
1560/** 1555/**
@@ -1581,40 +1576,40 @@ GNUNET_SCHEDULER_add_write_net (struct GNUNET_TIME_Relative delay,
1581 * only valid until "task" is started! 1576 * only valid until "task" is started!
1582 */ 1577 */
1583struct GNUNET_SCHEDULER_Task * 1578struct GNUNET_SCHEDULER_Task *
1584GNUNET_SCHEDULER_add_net_with_priority (struct GNUNET_TIME_Relative delay, 1579GNUNET_SCHEDULER_add_net_with_priority(struct GNUNET_TIME_Relative delay,
1585 enum GNUNET_SCHEDULER_Priority priority, 1580 enum GNUNET_SCHEDULER_Priority priority,
1586 struct GNUNET_NETWORK_Handle *fd, 1581 struct GNUNET_NETWORK_Handle *fd,
1587 int on_read, 1582 int on_read,
1588 int on_write, 1583 int on_write,
1589 GNUNET_SCHEDULER_TaskCallback task, 1584 GNUNET_SCHEDULER_TaskCallback task,
1590 void *task_cls) 1585 void *task_cls)
1591{ 1586{
1592 /* scheduler must be running */ 1587 /* scheduler must be running */
1593 GNUNET_assert (NULL != scheduler_driver); 1588 GNUNET_assert(NULL != scheduler_driver);
1594 1589
1595#if MINGW 1590#if MINGW
1596 struct GNUNET_NETWORK_FDSet *s; 1591 struct GNUNET_NETWORK_FDSet *s;
1597 struct GNUNET_SCHEDULER_Task * ret; 1592 struct GNUNET_SCHEDULER_Task * ret;
1598 1593
1599 GNUNET_assert (NULL != fd); 1594 GNUNET_assert(NULL != fd);
1600 s = GNUNET_NETWORK_fdset_create (); 1595 s = GNUNET_NETWORK_fdset_create();
1601 GNUNET_NETWORK_fdset_set (s, fd); 1596 GNUNET_NETWORK_fdset_set(s, fd);
1602 ret = GNUNET_SCHEDULER_add_select ( 1597 ret = GNUNET_SCHEDULER_add_select(
1603 priority, delay, 1598 priority, delay,
1604 on_read ? s : NULL, 1599 on_read ? s : NULL,
1605 on_write ? s : NULL, 1600 on_write ? s : NULL,
1606 task, task_cls); 1601 task, task_cls);
1607 GNUNET_NETWORK_fdset_destroy (s); 1602 GNUNET_NETWORK_fdset_destroy(s);
1608 return ret; 1603 return ret;
1609#else 1604#else
1610 GNUNET_assert (on_read || on_write); 1605 GNUNET_assert(on_read || on_write);
1611 GNUNET_assert (GNUNET_NETWORK_get_fd (fd) >= 0); 1606 GNUNET_assert(GNUNET_NETWORK_get_fd(fd) >= 0);
1612 return add_without_sets (delay, priority, 1607 return add_without_sets(delay, priority,
1613 on_read ? fd : NULL, 1608 on_read ? fd : NULL,
1614 on_write ? fd : NULL, 1609 on_write ? fd : NULL,
1615 NULL, 1610 NULL,
1616 NULL, 1611 NULL,
1617 task, task_cls); 1612 task, task_cls);
1618#endif 1613#endif
1619} 1614}
1620 1615
@@ -1640,14 +1635,14 @@ GNUNET_SCHEDULER_add_net_with_priority (struct GNUNET_TIME_Relative delay,
1640 * only valid until @a task is started! 1635 * only valid until @a task is started!
1641 */ 1636 */
1642struct GNUNET_SCHEDULER_Task * 1637struct GNUNET_SCHEDULER_Task *
1643GNUNET_SCHEDULER_add_read_file (struct GNUNET_TIME_Relative delay, 1638GNUNET_SCHEDULER_add_read_file(struct GNUNET_TIME_Relative delay,
1644 const struct GNUNET_DISK_FileHandle *rfd, 1639 const struct GNUNET_DISK_FileHandle *rfd,
1645 GNUNET_SCHEDULER_TaskCallback task, void *task_cls) 1640 GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
1646{ 1641{
1647 return GNUNET_SCHEDULER_add_file_with_priority ( 1642 return GNUNET_SCHEDULER_add_file_with_priority(
1648 delay, GNUNET_SCHEDULER_PRIORITY_DEFAULT, 1643 delay, GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1649 rfd, GNUNET_YES, GNUNET_NO, 1644 rfd, GNUNET_YES, GNUNET_NO,
1650 task, task_cls); 1645 task, task_cls);
1651} 1646}
1652 1647
1653 1648
@@ -1672,14 +1667,14 @@ GNUNET_SCHEDULER_add_read_file (struct GNUNET_TIME_Relative delay,
1672 * only valid until @a task is started! 1667 * only valid until @a task is started!
1673 */ 1668 */
1674struct GNUNET_SCHEDULER_Task * 1669struct GNUNET_SCHEDULER_Task *
1675GNUNET_SCHEDULER_add_write_file (struct GNUNET_TIME_Relative delay, 1670GNUNET_SCHEDULER_add_write_file(struct GNUNET_TIME_Relative delay,
1676 const struct GNUNET_DISK_FileHandle *wfd, 1671 const struct GNUNET_DISK_FileHandle *wfd,
1677 GNUNET_SCHEDULER_TaskCallback task, void *task_cls) 1672 GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
1678{ 1673{
1679 return GNUNET_SCHEDULER_add_file_with_priority ( 1674 return GNUNET_SCHEDULER_add_file_with_priority(
1680 delay, GNUNET_SCHEDULER_PRIORITY_DEFAULT, 1675 delay, GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1681 wfd, GNUNET_NO, GNUNET_YES, 1676 wfd, GNUNET_NO, GNUNET_YES,
1682 task, task_cls); 1677 task, task_cls);
1683} 1678}
1684 1679
1685 1680
@@ -1707,48 +1702,48 @@ GNUNET_SCHEDULER_add_write_file (struct GNUNET_TIME_Relative delay,
1707 * only valid until @a task is started! 1702 * only valid until @a task is started!
1708 */ 1703 */
1709struct GNUNET_SCHEDULER_Task * 1704struct GNUNET_SCHEDULER_Task *
1710GNUNET_SCHEDULER_add_file_with_priority (struct GNUNET_TIME_Relative delay, 1705GNUNET_SCHEDULER_add_file_with_priority(struct GNUNET_TIME_Relative delay,
1711 enum GNUNET_SCHEDULER_Priority priority, 1706 enum GNUNET_SCHEDULER_Priority priority,
1712 const struct GNUNET_DISK_FileHandle *fd, 1707 const struct GNUNET_DISK_FileHandle *fd,
1713 int on_read, int on_write, 1708 int on_read, int on_write,
1714 GNUNET_SCHEDULER_TaskCallback task, void *task_cls) 1709 GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
1715{ 1710{
1716 /* scheduler must be running */ 1711 /* scheduler must be running */
1717 GNUNET_assert (NULL != scheduler_driver); 1712 GNUNET_assert(NULL != scheduler_driver);
1718 1713
1719#if MINGW 1714#if MINGW
1720 struct GNUNET_NETWORK_FDSet *s; 1715 struct GNUNET_NETWORK_FDSet *s;
1721 struct GNUNET_SCHEDULER_Task * ret; 1716 struct GNUNET_SCHEDULER_Task * ret;
1722 1717
1723 GNUNET_assert (NULL != fd); 1718 GNUNET_assert(NULL != fd);
1724 s = GNUNET_NETWORK_fdset_create (); 1719 s = GNUNET_NETWORK_fdset_create();
1725 GNUNET_NETWORK_fdset_handle_set (s, fd); 1720 GNUNET_NETWORK_fdset_handle_set(s, fd);
1726 ret = GNUNET_SCHEDULER_add_select ( 1721 ret = GNUNET_SCHEDULER_add_select(
1727 priority, delay, 1722 priority, delay,
1728 on_read ? s : NULL, 1723 on_read ? s : NULL,
1729 on_write ? s : NULL, 1724 on_write ? s : NULL,
1730 task, task_cls); 1725 task, task_cls);
1731 GNUNET_NETWORK_fdset_destroy (s); 1726 GNUNET_NETWORK_fdset_destroy(s);
1732 return ret; 1727 return ret;
1733#else 1728#else
1734 GNUNET_assert (on_read || on_write); 1729 GNUNET_assert(on_read || on_write);
1735 GNUNET_assert (fd->fd >= 0); 1730 GNUNET_assert(fd->fd >= 0);
1736 return add_without_sets (delay, priority, 1731 return add_without_sets(delay, priority,
1737 NULL, 1732 NULL,
1738 NULL, 1733 NULL,
1739 on_read ? fd : NULL, 1734 on_read ? fd : NULL,
1740 on_write ? fd : NULL, 1735 on_write ? fd : NULL,
1741 task, task_cls); 1736 task, task_cls);
1742#endif 1737#endif
1743} 1738}
1744 1739
1745 1740
1746void 1741void
1747extract_handles (const struct GNUNET_NETWORK_FDSet *fdset, 1742extract_handles(const struct GNUNET_NETWORK_FDSet *fdset,
1748 const struct GNUNET_NETWORK_Handle ***ntarget, 1743 const struct GNUNET_NETWORK_Handle ***ntarget,
1749 unsigned int *extracted_nhandles, 1744 unsigned int *extracted_nhandles,
1750 const struct GNUNET_DISK_FileHandle ***ftarget, 1745 const struct GNUNET_DISK_FileHandle ***ftarget,
1751 unsigned int *extracted_fhandles) 1746 unsigned int *extracted_fhandles)
1752{ 1747{
1753 // FIXME: this implementation only works for unix, for WIN32 the file handles 1748 // FIXME: this implementation only works for unix, for WIN32 the file handles
1754 // in fdset must be handled separately 1749 // in fdset must be handled separately
@@ -1762,31 +1757,31 @@ extract_handles (const struct GNUNET_NETWORK_FDSet *fdset,
1762 nhandles_len = 0; 1757 nhandles_len = 0;
1763 fhandles_len = 0; 1758 fhandles_len = 0;
1764 for (int sock = 0; sock != fdset->nsds; ++sock) 1759 for (int sock = 0; sock != fdset->nsds; ++sock)
1765 {
1766 if (GNUNET_YES == GNUNET_NETWORK_fdset_test_native (fdset, sock))
1767 { 1760 {
1768 struct GNUNET_NETWORK_Handle *nhandle; 1761 if (GNUNET_YES == GNUNET_NETWORK_fdset_test_native(fdset, sock))
1769 struct GNUNET_DISK_FileHandle *fhandle;
1770
1771 nhandle = GNUNET_NETWORK_socket_box_native (sock);
1772 if (NULL != nhandle)
1773 {
1774 GNUNET_array_append (nhandles, nhandles_len, nhandle);
1775 }
1776 else
1777 {
1778 fhandle = GNUNET_DISK_get_handle_from_int_fd (sock);
1779 if (NULL != fhandle)
1780 { 1762 {
1781 GNUNET_array_append (fhandles, fhandles_len, fhandle); 1763 struct GNUNET_NETWORK_Handle *nhandle;
1764 struct GNUNET_DISK_FileHandle *fhandle;
1765
1766 nhandle = GNUNET_NETWORK_socket_box_native(sock);
1767 if (NULL != nhandle)
1768 {
1769 GNUNET_array_append(nhandles, nhandles_len, nhandle);
1770 }
1771 else
1772 {
1773 fhandle = GNUNET_DISK_get_handle_from_int_fd(sock);
1774 if (NULL != fhandle)
1775 {
1776 GNUNET_array_append(fhandles, fhandles_len, fhandle);
1777 }
1778 else
1779 {
1780 GNUNET_assert(0);
1781 }
1782 }
1782 } 1783 }
1783 else
1784 {
1785 GNUNET_assert (0);
1786 }
1787 }
1788 } 1784 }
1789 }
1790 *ntarget = nhandles_len > 0 ? nhandles : NULL; 1785 *ntarget = nhandles_len > 0 ? nhandles : NULL;
1791 *ftarget = fhandles_len > 0 ? fhandles : NULL; 1786 *ftarget = fhandles_len > 0 ? fhandles : NULL;
1792 *extracted_nhandles = nhandles_len; 1787 *extracted_nhandles = nhandles_len;
@@ -1826,12 +1821,12 @@ extract_handles (const struct GNUNET_NETWORK_FDSet *fdset,
1826 * only valid until @a task is started! 1821 * only valid until @a task is started!
1827 */ 1822 */
1828struct GNUNET_SCHEDULER_Task * 1823struct GNUNET_SCHEDULER_Task *
1829GNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio, 1824GNUNET_SCHEDULER_add_select(enum GNUNET_SCHEDULER_Priority prio,
1830 struct GNUNET_TIME_Relative delay, 1825 struct GNUNET_TIME_Relative delay,
1831 const struct GNUNET_NETWORK_FDSet *rs, 1826 const struct GNUNET_NETWORK_FDSet *rs,
1832 const struct GNUNET_NETWORK_FDSet *ws, 1827 const struct GNUNET_NETWORK_FDSet *ws,
1833 GNUNET_SCHEDULER_TaskCallback task, 1828 GNUNET_SCHEDULER_TaskCallback task,
1834 void *task_cls) 1829 void *task_cls)
1835{ 1830{
1836 struct GNUNET_SCHEDULER_Task *t; 1831 struct GNUNET_SCHEDULER_Task *t;
1837 const struct GNUNET_NETWORK_Handle **read_nhandles = NULL; 1832 const struct GNUNET_NETWORK_Handle **read_nhandles = NULL;
@@ -1844,8 +1839,8 @@ GNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio,
1844 unsigned int write_fhandles_len = 0; 1839 unsigned int write_fhandles_len = 0;
1845 1840
1846 /* scheduler must be running */ 1841 /* scheduler must be running */
1847 GNUNET_assert (NULL != scheduler_driver); 1842 GNUNET_assert(NULL != scheduler_driver);
1848 GNUNET_assert (NULL != task); 1843 GNUNET_assert(NULL != task);
1849 int no_rs = (NULL == rs); 1844 int no_rs = (NULL == rs);
1850 int no_ws = (NULL == ws); 1845 int no_ws = (NULL == ws);
1851 int empty_rs = (NULL != rs) && (0 == rs->nsds); 1846 int empty_rs = (NULL != rs) && (0 == rs->nsds);
@@ -1854,25 +1849,25 @@ GNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio,
1854 (empty_rs && empty_ws) || 1849 (empty_rs && empty_ws) ||
1855 (no_rs && empty_ws) || 1850 (no_rs && empty_ws) ||
1856 (no_ws && empty_rs); 1851 (no_ws && empty_rs);
1857 if (! no_fds) 1852 if (!no_fds)
1858 {
1859 if (NULL != rs)
1860 { 1853 {
1861 extract_handles (rs, 1854 if (NULL != rs)
1862 &read_nhandles, 1855 {
1863 &read_nhandles_len, 1856 extract_handles(rs,
1864 &read_fhandles, 1857 &read_nhandles,
1865 &read_fhandles_len); 1858 &read_nhandles_len,
1866 } 1859 &read_fhandles,
1867 if (NULL != ws) 1860 &read_fhandles_len);
1868 { 1861 }
1869 extract_handles (ws, 1862 if (NULL != ws)
1870 &write_nhandles, 1863 {
1871 &write_nhandles_len, 1864 extract_handles(ws,
1872 &write_fhandles, 1865 &write_nhandles,
1873 &write_fhandles_len); 1866 &write_nhandles_len,
1867 &write_fhandles,
1868 &write_fhandles_len);
1869 }
1874 } 1870 }
1875 }
1876 /** 1871 /**
1877 * here we consider the case that a GNUNET_NETWORK_FDSet might be empty 1872 * here we consider the case that a GNUNET_NETWORK_FDSet might be empty
1878 * although its maximum FD number (nsds) is greater than 0. We handle 1873 * although its maximum FD number (nsds) is greater than 0. We handle
@@ -1885,49 +1880,49 @@ GNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio,
1885 (0 == write_nhandles_len) && 1880 (0 == write_nhandles_len) &&
1886 (0 == write_fhandles_len); 1881 (0 == write_fhandles_len);
1887 if (no_fds || no_fds_extracted) 1882 if (no_fds || no_fds_extracted)
1888 return GNUNET_SCHEDULER_add_delayed_with_priority (delay, 1883 return GNUNET_SCHEDULER_add_delayed_with_priority(delay,
1889 prio, 1884 prio,
1890 task, 1885 task,
1891 task_cls); 1886 task_cls);
1892 t = GNUNET_new (struct GNUNET_SCHEDULER_Task); 1887 t = GNUNET_new(struct GNUNET_SCHEDULER_Task);
1893 GNUNET_async_scope_get (&t->scope); 1888 GNUNET_async_scope_get(&t->scope);
1894 init_fd_info (t, 1889 init_fd_info(t,
1895 read_nhandles, 1890 read_nhandles,
1896 read_nhandles_len, 1891 read_nhandles_len,
1897 write_nhandles, 1892 write_nhandles,
1898 write_nhandles_len, 1893 write_nhandles_len,
1899 read_fhandles, 1894 read_fhandles,
1900 read_fhandles_len, 1895 read_fhandles_len,
1901 write_fhandles, 1896 write_fhandles,
1902 write_fhandles_len); 1897 write_fhandles_len);
1903 t->callback = task; 1898 t->callback = task;
1904 t->callback_cls = task_cls; 1899 t->callback_cls = task_cls;
1905 t->own_handles = GNUNET_YES; 1900 t->own_handles = GNUNET_YES;
1906 /* free the arrays of pointers to network / file handles, the actual 1901 /* free the arrays of pointers to network / file handles, the actual
1907 * handles will be freed in destroy_task */ 1902 * handles will be freed in destroy_task */
1908 GNUNET_array_grow (read_nhandles, read_nhandles_len, 0); 1903 GNUNET_array_grow(read_nhandles, read_nhandles_len, 0);
1909 GNUNET_array_grow (write_nhandles, write_nhandles_len, 0); 1904 GNUNET_array_grow(write_nhandles, write_nhandles_len, 0);
1910 GNUNET_array_grow (read_fhandles, read_fhandles_len, 0); 1905 GNUNET_array_grow(read_fhandles, read_fhandles_len, 0);
1911 GNUNET_array_grow (write_fhandles, write_fhandles_len, 0); 1906 GNUNET_array_grow(write_fhandles, write_fhandles_len, 0);
1912#if PROFILE_DELAYS 1907#if PROFILE_DELAYS
1913 t->start_time = GNUNET_TIME_absolute_get (); 1908 t->start_time = GNUNET_TIME_absolute_get();
1914#endif 1909#endif
1915 t->timeout = GNUNET_TIME_relative_to_absolute (delay); 1910 t->timeout = GNUNET_TIME_relative_to_absolute(delay);
1916 t->priority = 1911 t->priority =
1917 check_priority ((prio == 1912 check_priority((prio ==
1918 GNUNET_SCHEDULER_PRIORITY_KEEP) ? current_priority : 1913 GNUNET_SCHEDULER_PRIORITY_KEEP) ? current_priority :
1919 prio); 1914 prio);
1920 t->lifeness = current_lifeness; 1915 t->lifeness = current_lifeness;
1921 GNUNET_CONTAINER_DLL_insert (pending_head, 1916 GNUNET_CONTAINER_DLL_insert(pending_head,
1922 pending_tail, 1917 pending_tail,
1923 t); 1918 t);
1924 driver_add_multiple (t); 1919 driver_add_multiple(t);
1925 max_priority_added = GNUNET_MAX (max_priority_added, 1920 max_priority_added = GNUNET_MAX(max_priority_added,
1926 t->priority); 1921 t->priority);
1927 LOG (GNUNET_ERROR_TYPE_DEBUG, 1922 LOG(GNUNET_ERROR_TYPE_DEBUG,
1928 "Adding task %p\n", 1923 "Adding task %p\n",
1929 t); 1924 t);
1930 init_backtrace (t); 1925 init_backtrace(t);
1931 return t; 1926 return t;
1932} 1927}
1933 1928
@@ -1944,27 +1939,27 @@ GNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio,
1944 * @param fdi information about the related FD 1939 * @param fdi information about the related FD
1945 */ 1940 */
1946void 1941void
1947GNUNET_SCHEDULER_task_ready (struct GNUNET_SCHEDULER_Task *task, 1942GNUNET_SCHEDULER_task_ready(struct GNUNET_SCHEDULER_Task *task,
1948 struct GNUNET_SCHEDULER_FdInfo *fdi) 1943 struct GNUNET_SCHEDULER_FdInfo *fdi)
1949{ 1944{
1950 enum GNUNET_SCHEDULER_Reason reason; 1945 enum GNUNET_SCHEDULER_Reason reason;
1951 1946
1952 reason = task->reason; 1947 reason = task->reason;
1953 if ( (0 == (reason & GNUNET_SCHEDULER_REASON_READ_READY)) && 1948 if ((0 == (reason & GNUNET_SCHEDULER_REASON_READ_READY)) &&
1954 (0 != (GNUNET_SCHEDULER_ET_IN & fdi->et)) ) 1949 (0 != (GNUNET_SCHEDULER_ET_IN & fdi->et)))
1955 reason |= GNUNET_SCHEDULER_REASON_READ_READY; 1950 reason |= GNUNET_SCHEDULER_REASON_READ_READY;
1956 if ( (0 == (reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) && 1951 if ((0 == (reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) &&
1957 (0 != (GNUNET_SCHEDULER_ET_OUT & fdi->et)) ) 1952 (0 != (GNUNET_SCHEDULER_ET_OUT & fdi->et)))
1958 reason |= GNUNET_SCHEDULER_REASON_WRITE_READY; 1953 reason |= GNUNET_SCHEDULER_REASON_WRITE_READY;
1959 reason |= GNUNET_SCHEDULER_REASON_PREREQ_DONE; 1954 reason |= GNUNET_SCHEDULER_REASON_PREREQ_DONE;
1960 task->reason = reason; 1955 task->reason = reason;
1961 if (GNUNET_NO == task->in_ready_list) 1956 if (GNUNET_NO == task->in_ready_list)
1962 { 1957 {
1963 GNUNET_CONTAINER_DLL_remove (pending_head, 1958 GNUNET_CONTAINER_DLL_remove(pending_head,
1964 pending_tail, 1959 pending_tail,
1965 task); 1960 task);
1966 queue_ready_task (task); 1961 queue_ready_task(task);
1967 } 1962 }
1968} 1963}
1969 1964
1970 1965
@@ -1989,173 +1984,173 @@ GNUNET_SCHEDULER_task_ready (struct GNUNET_SCHEDULER_Task *task,
1989 * if we are done running tasks (yield to block) 1984 * if we are done running tasks (yield to block)
1990 */ 1985 */
1991int 1986int
1992GNUNET_SCHEDULER_do_work (struct GNUNET_SCHEDULER_Handle *sh) 1987GNUNET_SCHEDULER_do_work(struct GNUNET_SCHEDULER_Handle *sh)
1993{ 1988{
1994 enum GNUNET_SCHEDULER_Priority p; 1989 enum GNUNET_SCHEDULER_Priority p;
1995 struct GNUNET_SCHEDULER_Task *pos; 1990 struct GNUNET_SCHEDULER_Task *pos;
1996 struct GNUNET_TIME_Absolute now; 1991 struct GNUNET_TIME_Absolute now;
1997 1992
1998 /* check for tasks that reached the timeout! */ 1993 /* check for tasks that reached the timeout! */
1999 now = GNUNET_TIME_absolute_get (); 1994 now = GNUNET_TIME_absolute_get();
2000 pos = pending_timeout_head; 1995 pos = pending_timeout_head;
2001 while (NULL != pos) 1996 while (NULL != pos)
2002 { 1997 {
2003 struct GNUNET_SCHEDULER_Task *next = pos->next; 1998 struct GNUNET_SCHEDULER_Task *next = pos->next;
2004 if (now.abs_value_us >= pos->timeout.abs_value_us) 1999 if (now.abs_value_us >= pos->timeout.abs_value_us)
2005 pos->reason |= GNUNET_SCHEDULER_REASON_TIMEOUT; 2000 pos->reason |= GNUNET_SCHEDULER_REASON_TIMEOUT;
2006 if (0 == pos->reason) 2001 if (0 == pos->reason)
2007 break; 2002 break;
2008 GNUNET_CONTAINER_DLL_remove (pending_timeout_head, 2003 GNUNET_CONTAINER_DLL_remove(pending_timeout_head,
2009 pending_timeout_tail, 2004 pending_timeout_tail,
2010 pos); 2005 pos);
2011 if (pending_timeout_last == pos) 2006 if (pending_timeout_last == pos)
2012 pending_timeout_last = NULL; 2007 pending_timeout_last = NULL;
2013 queue_ready_task (pos); 2008 queue_ready_task(pos);
2014 pos = next; 2009 pos = next;
2015 } 2010 }
2016 pos = pending_head; 2011 pos = pending_head;
2017 while (NULL != pos) 2012 while (NULL != pos)
2018 {
2019 struct GNUNET_SCHEDULER_Task *next = pos->next;
2020 if (now.abs_value_us >= pos->timeout.abs_value_us)
2021 { 2013 {
2022 pos->reason |= GNUNET_SCHEDULER_REASON_TIMEOUT; 2014 struct GNUNET_SCHEDULER_Task *next = pos->next;
2023 GNUNET_CONTAINER_DLL_remove (pending_head, 2015 if (now.abs_value_us >= pos->timeout.abs_value_us)
2024 pending_tail, 2016 {
2025 pos); 2017 pos->reason |= GNUNET_SCHEDULER_REASON_TIMEOUT;
2026 queue_ready_task (pos); 2018 GNUNET_CONTAINER_DLL_remove(pending_head,
2019 pending_tail,
2020 pos);
2021 queue_ready_task(pos);
2022 }
2023 pos = next;
2027 } 2024 }
2028 pos = next;
2029 }
2030 2025
2031 if (0 == ready_count) 2026 if (0 == ready_count)
2032 {
2033 struct GNUNET_TIME_Absolute timeout = get_timeout ();
2034
2035 if (timeout.abs_value_us > now.abs_value_us)
2036 {
2037 /**
2038 * The event loop called this function before the current timeout was
2039 * reached (and no FD tasks are ready). This is acceptable if
2040 *
2041 * - the system time was changed while the driver was waiting for
2042 * the timeout
2043 * - an external event loop called GNUnet API functions outside of
2044 * the callbacks called in GNUNET_SCHEDULER_do_work and thus
2045 * wasn't notified about the new timeout
2046 *
2047 * It might also mean we are busy-waiting because of a programming
2048 * error in the external event loop.
2049 */
2050 LOG (GNUNET_ERROR_TYPE_DEBUG,
2051 "GNUNET_SCHEDULER_do_work did not find any ready "
2052 "tasks and timeout has not been reached yet.\n");
2053 }
2054 else
2055 {
2056 /**
2057 * the current timeout was reached but no ready tasks were found,
2058 * internal scheduler error!
2059 */
2060 GNUNET_assert (0);
2061 }
2062 }
2063 else
2064 {
2065 /* find out which task priority level we are going to
2066 process this time */
2067 max_priority_added = GNUNET_SCHEDULER_PRIORITY_KEEP;
2068 GNUNET_assert (NULL == ready_head[GNUNET_SCHEDULER_PRIORITY_KEEP]);
2069 /* yes, p>0 is correct, 0 is "KEEP" which should
2070 * always be an empty queue (see assertion)! */
2071 for (p = GNUNET_SCHEDULER_PRIORITY_COUNT - 1; p > 0; p--)
2072 { 2027 {
2073 pos = ready_head[p]; 2028 struct GNUNET_TIME_Absolute timeout = get_timeout();
2074 if (NULL != pos)
2075 break;
2076 }
2077 GNUNET_assert (NULL != pos); /* ready_count wrong? */
2078 2029
2079 /* process all tasks at this priority level, then yield */ 2030 if (timeout.abs_value_us > now.abs_value_us)
2080 while (NULL != (pos = ready_head[p]))
2081 {
2082 GNUNET_CONTAINER_DLL_remove (ready_head[p],
2083 ready_tail[p],
2084 pos);
2085 ready_count--;
2086 current_priority = pos->priority;
2087 current_lifeness = pos->lifeness;
2088 active_task = pos;
2089#if PROFILE_DELAYS
2090 if (GNUNET_TIME_absolute_get_duration (pos->start_time).rel_value_us >
2091 DELAY_THRESHOLD.rel_value_us)
2092 {
2093 LOG (GNUNET_ERROR_TYPE_DEBUG,
2094 "Task %p took %s to be scheduled\n",
2095 pos,
2096 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (pos->start_time),
2097 GNUNET_YES));
2098 }
2099#endif
2100 tc.reason = pos->reason;
2101 GNUNET_NETWORK_fdset_zero (sh->rs);
2102 GNUNET_NETWORK_fdset_zero (sh->ws);
2103 // FIXME: do we have to remove FdInfos from fds if they are not ready?
2104 tc.fds_len = pos->fds_len;
2105 tc.fds = pos->fds;
2106 for (unsigned int i = 0; i != pos->fds_len; ++i)
2107 {
2108 struct GNUNET_SCHEDULER_FdInfo *fdi = &pos->fds[i];
2109 if (0 != (GNUNET_SCHEDULER_ET_IN & fdi->et))
2110 { 2031 {
2111 GNUNET_NETWORK_fdset_set_native (sh->rs, 2032 /**
2112 fdi->sock); 2033 * The event loop called this function before the current timeout was
2034 * reached (and no FD tasks are ready). This is acceptable if
2035 *
2036 * - the system time was changed while the driver was waiting for
2037 * the timeout
2038 * - an external event loop called GNUnet API functions outside of
2039 * the callbacks called in GNUNET_SCHEDULER_do_work and thus
2040 * wasn't notified about the new timeout
2041 *
2042 * It might also mean we are busy-waiting because of a programming
2043 * error in the external event loop.
2044 */
2045 LOG(GNUNET_ERROR_TYPE_DEBUG,
2046 "GNUNET_SCHEDULER_do_work did not find any ready "
2047 "tasks and timeout has not been reached yet.\n");
2113 } 2048 }
2114 if (0 != (GNUNET_SCHEDULER_ET_OUT & fdi->et)) 2049 else
2115 { 2050 {
2116 GNUNET_NETWORK_fdset_set_native (sh->ws, 2051 /**
2117 fdi->sock); 2052 * the current timeout was reached but no ready tasks were found,
2053 * internal scheduler error!
2054 */
2055 GNUNET_assert(0);
2118 } 2056 }
2119 } 2057 }
2120 tc.read_ready = sh->rs; 2058 else
2121 tc.write_ready = sh->ws; 2059 {
2122 LOG (GNUNET_ERROR_TYPE_DEBUG, 2060 /* find out which task priority level we are going to
2123 "Running task %p\n", 2061 process this time */
2124 pos); 2062 max_priority_added = GNUNET_SCHEDULER_PRIORITY_KEEP;
2125 GNUNET_assert (NULL != pos->callback); 2063 GNUNET_assert(NULL == ready_head[GNUNET_SCHEDULER_PRIORITY_KEEP]);
2126 { 2064 /* yes, p>0 is correct, 0 is "KEEP" which should
2127 struct GNUNET_AsyncScopeSave old_scope; 2065 * always be an empty queue (see assertion)! */
2128 if (pos->scope.have_scope) 2066 for (p = GNUNET_SCHEDULER_PRIORITY_COUNT - 1; p > 0; p--)
2129 GNUNET_async_scope_enter (&pos->scope.scope_id, &old_scope);
2130 else
2131 GNUNET_async_scope_get (&old_scope);
2132 pos->callback (pos->callback_cls);
2133 GNUNET_async_scope_restore (&old_scope);
2134 }
2135 if (NULL != pos->fds)
2136 {
2137 int del_result = scheduler_driver->del (scheduler_driver->cls, pos);
2138 if (GNUNET_OK != del_result)
2139 { 2067 {
2140 LOG (GNUNET_ERROR_TYPE_ERROR, 2068 pos = ready_head[p];
2141 "driver could not delete task %p\n", pos); 2069 if (NULL != pos)
2142 GNUNET_assert (0); 2070 break;
2071 }
2072 GNUNET_assert(NULL != pos); /* ready_count wrong? */
2073
2074 /* process all tasks at this priority level, then yield */
2075 while (NULL != (pos = ready_head[p]))
2076 {
2077 GNUNET_CONTAINER_DLL_remove(ready_head[p],
2078 ready_tail[p],
2079 pos);
2080 ready_count--;
2081 current_priority = pos->priority;
2082 current_lifeness = pos->lifeness;
2083 active_task = pos;
2084#if PROFILE_DELAYS
2085 if (GNUNET_TIME_absolute_get_duration(pos->start_time).rel_value_us >
2086 DELAY_THRESHOLD.rel_value_us)
2087 {
2088 LOG(GNUNET_ERROR_TYPE_DEBUG,
2089 "Task %p took %s to be scheduled\n",
2090 pos,
2091 GNUNET_STRINGS_relative_time_to_string(GNUNET_TIME_absolute_get_duration(pos->start_time),
2092 GNUNET_YES));
2093 }
2094#endif
2095 tc.reason = pos->reason;
2096 GNUNET_NETWORK_fdset_zero(sh->rs);
2097 GNUNET_NETWORK_fdset_zero(sh->ws);
2098 // FIXME: do we have to remove FdInfos from fds if they are not ready?
2099 tc.fds_len = pos->fds_len;
2100 tc.fds = pos->fds;
2101 for (unsigned int i = 0; i != pos->fds_len; ++i)
2102 {
2103 struct GNUNET_SCHEDULER_FdInfo *fdi = &pos->fds[i];
2104 if (0 != (GNUNET_SCHEDULER_ET_IN & fdi->et))
2105 {
2106 GNUNET_NETWORK_fdset_set_native(sh->rs,
2107 fdi->sock);
2108 }
2109 if (0 != (GNUNET_SCHEDULER_ET_OUT & fdi->et))
2110 {
2111 GNUNET_NETWORK_fdset_set_native(sh->ws,
2112 fdi->sock);
2113 }
2114 }
2115 tc.read_ready = sh->rs;
2116 tc.write_ready = sh->ws;
2117 LOG(GNUNET_ERROR_TYPE_DEBUG,
2118 "Running task %p\n",
2119 pos);
2120 GNUNET_assert(NULL != pos->callback);
2121 {
2122 struct GNUNET_AsyncScopeSave old_scope;
2123 if (pos->scope.have_scope)
2124 GNUNET_async_scope_enter(&pos->scope.scope_id, &old_scope);
2125 else
2126 GNUNET_async_scope_get(&old_scope);
2127 pos->callback(pos->callback_cls);
2128 GNUNET_async_scope_restore(&old_scope);
2129 }
2130 if (NULL != pos->fds)
2131 {
2132 int del_result = scheduler_driver->del(scheduler_driver->cls, pos);
2133 if (GNUNET_OK != del_result)
2134 {
2135 LOG(GNUNET_ERROR_TYPE_ERROR,
2136 "driver could not delete task %p\n", pos);
2137 GNUNET_assert(0);
2138 }
2139 }
2140 active_task = NULL;
2141 dump_backtrace(pos);
2142 destroy_task(pos);
2143 } 2143 }
2144 }
2145 active_task = NULL;
2146 dump_backtrace (pos);
2147 destroy_task (pos);
2148 } 2144 }
2149 } 2145 shutdown_if_no_lifeness();
2150 shutdown_if_no_lifeness ();
2151 if (0 == ready_count) 2146 if (0 == ready_count)
2152 { 2147 {
2153 scheduler_driver->set_wakeup (scheduler_driver->cls, 2148 scheduler_driver->set_wakeup(scheduler_driver->cls,
2154 get_timeout ()); 2149 get_timeout());
2155 return GNUNET_NO; 2150 return GNUNET_NO;
2156 } 2151 }
2157 scheduler_driver->set_wakeup (scheduler_driver->cls, 2152 scheduler_driver->set_wakeup(scheduler_driver->cls,
2158 GNUNET_TIME_absolute_get ()); 2153 GNUNET_TIME_absolute_get());
2159 return GNUNET_YES; 2154 return GNUNET_YES;
2160} 2155}
2161 2156
@@ -2192,64 +2187,64 @@ GNUNET_SCHEDULER_do_work (struct GNUNET_SCHEDULER_Handle *sh)
2192 * #GNUNET_SCHEDULER_driver_done 2187 * #GNUNET_SCHEDULER_driver_done
2193 */ 2188 */
2194struct GNUNET_SCHEDULER_Handle * 2189struct GNUNET_SCHEDULER_Handle *
2195GNUNET_SCHEDULER_driver_init (const struct GNUNET_SCHEDULER_Driver *driver) 2190GNUNET_SCHEDULER_driver_init(const struct GNUNET_SCHEDULER_Driver *driver)
2196{ 2191{
2197 struct GNUNET_SCHEDULER_Handle *sh; 2192 struct GNUNET_SCHEDULER_Handle *sh;
2198 const struct GNUNET_DISK_FileHandle *pr; 2193 const struct GNUNET_DISK_FileHandle *pr;
2199 2194
2200 /* scheduler must not be running */ 2195 /* scheduler must not be running */
2201 GNUNET_assert (NULL == scheduler_driver); 2196 GNUNET_assert(NULL == scheduler_driver);
2202 GNUNET_assert (NULL == shutdown_pipe_handle); 2197 GNUNET_assert(NULL == shutdown_pipe_handle);
2203 /* general set-up */ 2198 /* general set-up */
2204 sh = GNUNET_new (struct GNUNET_SCHEDULER_Handle); 2199 sh = GNUNET_new(struct GNUNET_SCHEDULER_Handle);
2205 shutdown_pipe_handle = GNUNET_DISK_pipe (GNUNET_NO, 2200 shutdown_pipe_handle = GNUNET_DISK_pipe(GNUNET_NO,
2206 GNUNET_NO, 2201 GNUNET_NO,
2207 GNUNET_NO, 2202 GNUNET_NO,
2208 GNUNET_NO); 2203 GNUNET_NO);
2209 GNUNET_assert (NULL != shutdown_pipe_handle); 2204 GNUNET_assert(NULL != shutdown_pipe_handle);
2210 pr = GNUNET_DISK_pipe_handle (shutdown_pipe_handle, 2205 pr = GNUNET_DISK_pipe_handle(shutdown_pipe_handle,
2211 GNUNET_DISK_PIPE_END_READ); 2206 GNUNET_DISK_PIPE_END_READ);
2212 my_pid = getpid (); 2207 my_pid = getpid();
2213 scheduler_driver = driver; 2208 scheduler_driver = driver;
2214 2209
2215 /* install signal handlers */ 2210 /* install signal handlers */
2216 LOG (GNUNET_ERROR_TYPE_DEBUG, 2211 LOG(GNUNET_ERROR_TYPE_DEBUG,
2217 "Registering signal handlers\n"); 2212 "Registering signal handlers\n");
2218 sh->shc_int = GNUNET_SIGNAL_handler_install (SIGINT, 2213 sh->shc_int = GNUNET_SIGNAL_handler_install(SIGINT,
2214 &sighandler_shutdown);
2215 sh->shc_term = GNUNET_SIGNAL_handler_install(SIGTERM,
2219 &sighandler_shutdown); 2216 &sighandler_shutdown);
2220 sh->shc_term = GNUNET_SIGNAL_handler_install (SIGTERM,
2221 &sighandler_shutdown);
2222#if (SIGTERM != GNUNET_TERM_SIG) 2217#if (SIGTERM != GNUNET_TERM_SIG)
2223 sh->shc_gterm = GNUNET_SIGNAL_handler_install (GNUNET_TERM_SIG, 2218 sh->shc_gterm = GNUNET_SIGNAL_handler_install(GNUNET_TERM_SIG,
2224 &sighandler_shutdown); 2219 &sighandler_shutdown);
2225#endif 2220#endif
2226#ifndef MINGW 2221#ifndef MINGW
2227 sh->shc_pipe = GNUNET_SIGNAL_handler_install (SIGPIPE, 2222 sh->shc_pipe = GNUNET_SIGNAL_handler_install(SIGPIPE,
2228 &sighandler_pipe); 2223 &sighandler_pipe);
2229 sh->shc_quit = GNUNET_SIGNAL_handler_install (SIGQUIT, 2224 sh->shc_quit = GNUNET_SIGNAL_handler_install(SIGQUIT,
2230 &sighandler_shutdown);
2231 sh->shc_hup = GNUNET_SIGNAL_handler_install (SIGHUP,
2232 &sighandler_shutdown); 2225 &sighandler_shutdown);
2226 sh->shc_hup = GNUNET_SIGNAL_handler_install(SIGHUP,
2227 &sighandler_shutdown);
2233#endif 2228#endif
2234 2229
2235 /* Setup initial tasks */ 2230 /* Setup initial tasks */
2236 current_priority = GNUNET_SCHEDULER_PRIORITY_DEFAULT; 2231 current_priority = GNUNET_SCHEDULER_PRIORITY_DEFAULT;
2237 current_lifeness = GNUNET_NO; 2232 current_lifeness = GNUNET_NO;
2238 install_parent_control_task = 2233 install_parent_control_task =
2239 GNUNET_SCHEDULER_add_now (&install_parent_control_handler, 2234 GNUNET_SCHEDULER_add_now(&install_parent_control_handler,
2240 NULL); 2235 NULL);
2241 shutdown_pipe_task = 2236 shutdown_pipe_task =
2242 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 2237 GNUNET_SCHEDULER_add_read_file(GNUNET_TIME_UNIT_FOREVER_REL,
2243 pr, 2238 pr,
2244 &shutdown_pipe_cb, 2239 &shutdown_pipe_cb,
2245 NULL); 2240 NULL);
2246 current_lifeness = GNUNET_YES; 2241 current_lifeness = GNUNET_YES;
2247 scheduler_driver->set_wakeup (scheduler_driver->cls, 2242 scheduler_driver->set_wakeup(scheduler_driver->cls,
2248 get_timeout ()); 2243 get_timeout());
2249 /* begin main event loop */ 2244 /* begin main event loop */
2250 sh->rs = GNUNET_NETWORK_fdset_create (); 2245 sh->rs = GNUNET_NETWORK_fdset_create();
2251 sh->ws = GNUNET_NETWORK_fdset_create (); 2246 sh->ws = GNUNET_NETWORK_fdset_create();
2252 GNUNET_NETWORK_fdset_handle_set (sh->rs, pr); 2247 GNUNET_NETWORK_fdset_handle_set(sh->rs, pr);
2253 return sh; 2248 return sh;
2254} 2249}
2255 2250
@@ -2269,244 +2264,245 @@ GNUNET_SCHEDULER_driver_init (const struct GNUNET_SCHEDULER_Driver *driver)
2269 * @param sh the handle returned by #GNUNET_SCHEDULER_driver_init 2264 * @param sh the handle returned by #GNUNET_SCHEDULER_driver_init
2270 */ 2265 */
2271void 2266void
2272GNUNET_SCHEDULER_driver_done (struct GNUNET_SCHEDULER_Handle *sh) 2267GNUNET_SCHEDULER_driver_done(struct GNUNET_SCHEDULER_Handle *sh)
2273{ 2268{
2274 GNUNET_assert (NULL == pending_head); 2269 GNUNET_assert(NULL == pending_head);
2275 GNUNET_assert (NULL == pending_timeout_head); 2270 GNUNET_assert(NULL == pending_timeout_head);
2276 GNUNET_assert (NULL == shutdown_head); 2271 GNUNET_assert(NULL == shutdown_head);
2277 for (int i = 0; i != GNUNET_SCHEDULER_PRIORITY_COUNT; ++i) 2272 for (int i = 0; i != GNUNET_SCHEDULER_PRIORITY_COUNT; ++i)
2278 { 2273 {
2279 GNUNET_assert (NULL == ready_head[i]); 2274 GNUNET_assert(NULL == ready_head[i]);
2280 } 2275 }
2281 GNUNET_NETWORK_fdset_destroy (sh->rs); 2276 GNUNET_NETWORK_fdset_destroy(sh->rs);
2282 GNUNET_NETWORK_fdset_destroy (sh->ws); 2277 GNUNET_NETWORK_fdset_destroy(sh->ws);
2283 2278
2284 /* uninstall signal handlers */ 2279 /* uninstall signal handlers */
2285 GNUNET_SIGNAL_handler_uninstall (sh->shc_int); 2280 GNUNET_SIGNAL_handler_uninstall(sh->shc_int);
2286 GNUNET_SIGNAL_handler_uninstall (sh->shc_term); 2281 GNUNET_SIGNAL_handler_uninstall(sh->shc_term);
2287#if (SIGTERM != GNUNET_TERM_SIG) 2282#if (SIGTERM != GNUNET_TERM_SIG)
2288 GNUNET_SIGNAL_handler_uninstall (sh->shc_gterm); 2283 GNUNET_SIGNAL_handler_uninstall(sh->shc_gterm);
2289#endif 2284#endif
2290#ifndef MINGW 2285#ifndef MINGW
2291 GNUNET_SIGNAL_handler_uninstall (sh->shc_pipe); 2286 GNUNET_SIGNAL_handler_uninstall(sh->shc_pipe);
2292 GNUNET_SIGNAL_handler_uninstall (sh->shc_quit); 2287 GNUNET_SIGNAL_handler_uninstall(sh->shc_quit);
2293 GNUNET_SIGNAL_handler_uninstall (sh->shc_hup); 2288 GNUNET_SIGNAL_handler_uninstall(sh->shc_hup);
2294#endif 2289#endif
2295 GNUNET_DISK_pipe_close (shutdown_pipe_handle); 2290 GNUNET_DISK_pipe_close(shutdown_pipe_handle);
2296 shutdown_pipe_handle = NULL; 2291 shutdown_pipe_handle = NULL;
2297 scheduler_driver = NULL; 2292 scheduler_driver = NULL;
2298 GNUNET_free (sh); 2293 GNUNET_free(sh);
2299} 2294}
2300 2295
2301 2296
2302static int 2297static int
2303select_loop (struct GNUNET_SCHEDULER_Handle *sh, 2298select_loop(struct GNUNET_SCHEDULER_Handle *sh,
2304 struct DriverContext *context) 2299 struct DriverContext *context)
2305{ 2300{
2306 struct GNUNET_NETWORK_FDSet *rs; 2301 struct GNUNET_NETWORK_FDSet *rs;
2307 struct GNUNET_NETWORK_FDSet *ws; 2302 struct GNUNET_NETWORK_FDSet *ws;
2308 int select_result; 2303 int select_result;
2309 2304
2310 GNUNET_assert (NULL != context); 2305 GNUNET_assert(NULL != context);
2311 rs = GNUNET_NETWORK_fdset_create (); 2306 rs = GNUNET_NETWORK_fdset_create();
2312 ws = GNUNET_NETWORK_fdset_create (); 2307 ws = GNUNET_NETWORK_fdset_create();
2313 while ( (NULL != context->scheduled_head) || 2308 while ((NULL != context->scheduled_head) ||
2314 (GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us != context->timeout.abs_value_us) ) 2309 (GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us != context->timeout.abs_value_us))
2315 {
2316 LOG (GNUNET_ERROR_TYPE_DEBUG,
2317 "select timeout = %s\n",
2318 GNUNET_STRINGS_absolute_time_to_string (context->timeout));
2319
2320 GNUNET_NETWORK_fdset_zero (rs);
2321 GNUNET_NETWORK_fdset_zero (ws);
2322
2323 for (struct Scheduled *pos = context->scheduled_head;
2324 NULL != pos;
2325 pos = pos->next)
2326 { 2310 {
2327 if (0 != (GNUNET_SCHEDULER_ET_IN & pos->et)) 2311 LOG(GNUNET_ERROR_TYPE_DEBUG,
2328 { 2312 "select timeout = %s\n",
2329 GNUNET_NETWORK_fdset_set_native (rs, pos->fdi->sock); 2313 GNUNET_STRINGS_absolute_time_to_string(context->timeout));
2330 } 2314
2331 if (0 != (GNUNET_SCHEDULER_ET_OUT & pos->et)) 2315 GNUNET_NETWORK_fdset_zero(rs);
2332 { 2316 GNUNET_NETWORK_fdset_zero(ws);
2333 GNUNET_NETWORK_fdset_set_native (ws, pos->fdi->sock);
2334 }
2335 }
2336 struct GNUNET_TIME_Relative time_remaining =
2337 GNUNET_TIME_absolute_get_remaining (context->timeout);
2338 if (NULL == scheduler_select)
2339 {
2340 select_result = GNUNET_NETWORK_socket_select (rs,
2341 ws,
2342 NULL,
2343 time_remaining);
2344 }
2345 else
2346 {
2347 select_result = scheduler_select (scheduler_select_cls,
2348 rs,
2349 ws,
2350 NULL,
2351 time_remaining);
2352 }
2353 if (select_result == GNUNET_SYSERR)
2354 {
2355 if (errno == EINTR)
2356 continue;
2357 2317
2358 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, 2318 for (struct Scheduled *pos = context->scheduled_head;
2359 "select"); 2319 NULL != pos;
2320 pos = pos->next)
2321 {
2322 if (0 != (GNUNET_SCHEDULER_ET_IN & pos->et))
2323 {
2324 GNUNET_NETWORK_fdset_set_native(rs, pos->fdi->sock);
2325 }
2326 if (0 != (GNUNET_SCHEDULER_ET_OUT & pos->et))
2327 {
2328 GNUNET_NETWORK_fdset_set_native(ws, pos->fdi->sock);
2329 }
2330 }
2331 struct GNUNET_TIME_Relative time_remaining =
2332 GNUNET_TIME_absolute_get_remaining(context->timeout);
2333 if (NULL == scheduler_select)
2334 {
2335 select_result = GNUNET_NETWORK_socket_select(rs,
2336 ws,
2337 NULL,
2338 time_remaining);
2339 }
2340 else
2341 {
2342 select_result = scheduler_select(scheduler_select_cls,
2343 rs,
2344 ws,
2345 NULL,
2346 time_remaining);
2347 }
2348 if (select_result == GNUNET_SYSERR)
2349 {
2350 if (errno == EINTR)
2351 continue;
2352
2353 LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR,
2354 "select");
2360#ifndef MINGW 2355#ifndef MINGW
2361#if USE_LSOF 2356#if USE_LSOF
2362 char lsof[512]; 2357 char lsof[512];
2363 2358
2364 snprintf (lsof, 2359 snprintf(lsof,
2365 sizeof (lsof), 2360 sizeof(lsof),
2366 "lsof -p %d", 2361 "lsof -p %d",
2367 getpid ()); 2362 getpid());
2368 (void) close (1); 2363 (void)close(1);
2369 (void) dup2 (2, 1); 2364 (void)dup2(2, 1);
2370 if (0 != system (lsof)) 2365 if (0 != system(lsof))
2371 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, 2366 LOG_STRERROR(GNUNET_ERROR_TYPE_WARNING,
2372 "system"); 2367 "system");
2373#endif 2368#endif
2374#endif 2369#endif
2375#if DEBUG_FDS 2370#if DEBUG_FDS
2376 for (struct Scheduled *s = context->scheduled_head; 2371 for (struct Scheduled *s = context->scheduled_head;
2377 NULL != s; 2372 NULL != s;
2378 s = s->next) 2373 s = s->next)
2379 { 2374 {
2380 int flags = fcntl (s->fdi->sock, 2375 int flags = fcntl(s->fdi->sock,
2381 F_GETFD); 2376 F_GETFD);
2382 2377
2383 if ( (flags == -1) && 2378 if ((flags == -1) &&
2384 (EBADF == errno) ) 2379 (EBADF == errno))
2385 { 2380 {
2386 LOG (GNUNET_ERROR_TYPE_ERROR, 2381 LOG(GNUNET_ERROR_TYPE_ERROR,
2387 "Got invalid file descriptor %d!\n", 2382 "Got invalid file descriptor %d!\n",
2388 s->fdi->sock); 2383 s->fdi->sock);
2389#if EXECINFO 2384#if EXECINFO
2390 dump_backtrace (s->task); 2385 dump_backtrace(s->task);
2391#endif 2386#endif
2392 } 2387 }
2393 } 2388 }
2394#endif 2389#endif
2395 GNUNET_assert (0); 2390 GNUNET_assert(0);
2396 GNUNET_NETWORK_fdset_destroy (rs); 2391 GNUNET_NETWORK_fdset_destroy(rs);
2397 GNUNET_NETWORK_fdset_destroy (ws); 2392 GNUNET_NETWORK_fdset_destroy(ws);
2398 return GNUNET_SYSERR; 2393 return GNUNET_SYSERR;
2399 }
2400 if (select_result > 0)
2401 {
2402 for (struct Scheduled *pos = context->scheduled_head;
2403 NULL != pos;
2404 pos = pos->next)
2405 {
2406 int is_ready = GNUNET_NO;
2407
2408 if (0 != (GNUNET_SCHEDULER_ET_IN & pos->et) &&
2409 GNUNET_YES ==
2410 GNUNET_NETWORK_fdset_test_native (rs,
2411 pos->fdi->sock))
2412 {
2413 pos->fdi->et |= GNUNET_SCHEDULER_ET_IN;
2414 is_ready = GNUNET_YES;
2415 } 2394 }
2416 if (0 != (GNUNET_SCHEDULER_ET_OUT & pos->et) && 2395 if (select_result > 0)
2417 GNUNET_YES ==
2418 GNUNET_NETWORK_fdset_test_native (ws,
2419 pos->fdi->sock))
2420 { 2396 {
2421 pos->fdi->et |= GNUNET_SCHEDULER_ET_OUT; 2397 for (struct Scheduled *pos = context->scheduled_head;
2422 is_ready = GNUNET_YES; 2398 NULL != pos;
2399 pos = pos->next)
2400 {
2401 int is_ready = GNUNET_NO;
2402
2403 if (0 != (GNUNET_SCHEDULER_ET_IN & pos->et) &&
2404 GNUNET_YES ==
2405 GNUNET_NETWORK_fdset_test_native(rs,
2406 pos->fdi->sock))
2407 {
2408 pos->fdi->et |= GNUNET_SCHEDULER_ET_IN;
2409 is_ready = GNUNET_YES;
2410 }
2411 if (0 != (GNUNET_SCHEDULER_ET_OUT & pos->et) &&
2412 GNUNET_YES ==
2413 GNUNET_NETWORK_fdset_test_native(ws,
2414 pos->fdi->sock))
2415 {
2416 pos->fdi->et |= GNUNET_SCHEDULER_ET_OUT;
2417 is_ready = GNUNET_YES;
2418 }
2419 if (GNUNET_YES == is_ready)
2420 {
2421 GNUNET_SCHEDULER_task_ready(pos->task,
2422 pos->fdi);
2423 }
2424 }
2423 } 2425 }
2424 if (GNUNET_YES == is_ready) 2426 if (GNUNET_YES == GNUNET_SCHEDULER_do_work(sh))
2425 { 2427 {
2426 GNUNET_SCHEDULER_task_ready (pos->task, 2428 LOG(GNUNET_ERROR_TYPE_DEBUG,
2427 pos->fdi); 2429 "scheduler has more tasks ready!\n");
2428 } 2430 }
2429 }
2430 } 2431 }
2431 if (GNUNET_YES == GNUNET_SCHEDULER_do_work (sh)) 2432 GNUNET_NETWORK_fdset_destroy(rs);
2432 { 2433 GNUNET_NETWORK_fdset_destroy(ws);
2433 LOG (GNUNET_ERROR_TYPE_DEBUG,
2434 "scheduler has more tasks ready!\n");
2435 }
2436 }
2437 GNUNET_NETWORK_fdset_destroy (rs);
2438 GNUNET_NETWORK_fdset_destroy (ws);
2439 return GNUNET_OK; 2434 return GNUNET_OK;
2440} 2435}
2441 2436
2442 2437
2443static int 2438static int
2444select_add (void *cls, 2439select_add(void *cls,
2445 struct GNUNET_SCHEDULER_Task *task, 2440 struct GNUNET_SCHEDULER_Task *task,
2446 struct GNUNET_SCHEDULER_FdInfo *fdi) 2441 struct GNUNET_SCHEDULER_FdInfo *fdi)
2447{ 2442{
2448 struct DriverContext *context = cls; 2443 struct DriverContext *context = cls;
2449 GNUNET_assert (NULL != context); 2444
2450 GNUNET_assert (NULL != task); 2445 GNUNET_assert(NULL != context);
2451 GNUNET_assert (NULL != fdi); 2446 GNUNET_assert(NULL != task);
2452 GNUNET_assert (0 != (GNUNET_SCHEDULER_ET_IN & fdi->et) || 2447 GNUNET_assert(NULL != fdi);
2453 0 != (GNUNET_SCHEDULER_ET_OUT & fdi->et)); 2448 GNUNET_assert(0 != (GNUNET_SCHEDULER_ET_IN & fdi->et) ||
2449 0 != (GNUNET_SCHEDULER_ET_OUT & fdi->et));
2454 2450
2455 if (!((NULL != fdi->fd) ^ (NULL != fdi->fh)) || (fdi->sock < 0)) 2451 if (!((NULL != fdi->fd) ^ (NULL != fdi->fh)) || (fdi->sock < 0))
2456 { 2452 {
2457 /* exactly one out of {fd, hf} must be != NULL and the OS handle must be valid */ 2453 /* exactly one out of {fd, hf} must be != NULL and the OS handle must be valid */
2458 return GNUNET_SYSERR; 2454 return GNUNET_SYSERR;
2459 } 2455 }
2460 2456
2461 struct Scheduled *scheduled = GNUNET_new (struct Scheduled); 2457 struct Scheduled *scheduled = GNUNET_new(struct Scheduled);
2462 scheduled->task = task; 2458 scheduled->task = task;
2463 scheduled->fdi = fdi; 2459 scheduled->fdi = fdi;
2464 scheduled->et = fdi->et; 2460 scheduled->et = fdi->et;
2465 2461
2466 GNUNET_CONTAINER_DLL_insert (context->scheduled_head, 2462 GNUNET_CONTAINER_DLL_insert(context->scheduled_head,
2467 context->scheduled_tail, 2463 context->scheduled_tail,
2468 scheduled); 2464 scheduled);
2469 return GNUNET_OK; 2465 return GNUNET_OK;
2470} 2466}
2471 2467
2472 2468
2473static int 2469static int
2474select_del (void *cls, 2470select_del(void *cls,
2475 struct GNUNET_SCHEDULER_Task *task) 2471 struct GNUNET_SCHEDULER_Task *task)
2476{ 2472{
2477 struct DriverContext *context; 2473 struct DriverContext *context;
2478 struct Scheduled *pos; 2474 struct Scheduled *pos;
2479 int ret; 2475 int ret;
2480 2476
2481 GNUNET_assert (NULL != cls); 2477 GNUNET_assert(NULL != cls);
2482 2478
2483 context = cls; 2479 context = cls;
2484 ret = GNUNET_SYSERR; 2480 ret = GNUNET_SYSERR;
2485 pos = context->scheduled_head; 2481 pos = context->scheduled_head;
2486 while (NULL != pos) 2482 while (NULL != pos)
2487 {
2488 struct Scheduled *next = pos->next;
2489 if (pos->task == task)
2490 { 2483 {
2491 GNUNET_CONTAINER_DLL_remove (context->scheduled_head, 2484 struct Scheduled *next = pos->next;
2492 context->scheduled_tail, 2485 if (pos->task == task)
2493 pos); 2486 {
2494 GNUNET_free (pos); 2487 GNUNET_CONTAINER_DLL_remove(context->scheduled_head,
2495 ret = GNUNET_OK; 2488 context->scheduled_tail,
2489 pos);
2490 GNUNET_free(pos);
2491 ret = GNUNET_OK;
2492 }
2493 pos = next;
2496 } 2494 }
2497 pos = next;
2498 }
2499 return ret; 2495 return ret;
2500} 2496}
2501 2497
2502 2498
2503static void 2499static void
2504select_set_wakeup (void *cls, 2500select_set_wakeup(void *cls,
2505 struct GNUNET_TIME_Absolute dt) 2501 struct GNUNET_TIME_Absolute dt)
2506{ 2502{
2507 struct DriverContext *context = cls; 2503 struct DriverContext *context = cls;
2508 2504
2509 GNUNET_assert (NULL != context); 2505 GNUNET_assert(NULL != context);
2510 context->timeout = dt; 2506 context->timeout = dt;
2511} 2507}
2512 2508
@@ -2517,10 +2513,11 @@ select_set_wakeup (void *cls,
2517 * @return NULL on error 2513 * @return NULL on error
2518 */ 2514 */
2519struct GNUNET_SCHEDULER_Driver * 2515struct GNUNET_SCHEDULER_Driver *
2520GNUNET_SCHEDULER_driver_select () 2516GNUNET_SCHEDULER_driver_select()
2521{ 2517{
2522 struct GNUNET_SCHEDULER_Driver *select_driver; 2518 struct GNUNET_SCHEDULER_Driver *select_driver;
2523 select_driver = GNUNET_new (struct GNUNET_SCHEDULER_Driver); 2519
2520 select_driver = GNUNET_new(struct GNUNET_SCHEDULER_Driver);
2524 2521
2525 select_driver->add = &select_add; 2522 select_driver->add = &select_add;
2526 select_driver->del = &select_del; 2523 select_driver->del = &select_del;
@@ -2543,14 +2540,14 @@ GNUNET_SCHEDULER_driver_select ()
2543 * @param aid the asynchronous scope id to enter 2540 * @param aid the asynchronous scope id to enter
2544 */ 2541 */
2545void 2542void
2546GNUNET_SCHEDULER_begin_async_scope (struct GNUNET_AsyncScopeId *aid) 2543GNUNET_SCHEDULER_begin_async_scope(struct GNUNET_AsyncScopeId *aid)
2547{ 2544{
2548 struct GNUNET_AsyncScopeSave dummy_old_scope; 2545 struct GNUNET_AsyncScopeSave dummy_old_scope;
2549 2546
2550 GNUNET_assert (NULL != active_task); 2547 GNUNET_assert(NULL != active_task);
2551 /* Since we're in a task, the context will be automatically 2548 /* Since we're in a task, the context will be automatically
2552 restored by the scheduler. */ 2549 restored by the scheduler. */
2553 GNUNET_async_scope_enter (aid, &dummy_old_scope); 2550 GNUNET_async_scope_enter(aid, &dummy_old_scope);
2554} 2551}
2555 2552
2556 2553