aboutsummaryrefslogtreecommitdiff
path: root/src/util/scheduler.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/scheduler.c')
-rw-r--r--src/util/scheduler.c851
1 files changed, 415 insertions, 436 deletions
diff --git a/src/util/scheduler.c b/src/util/scheduler.c
index e4a31c388..9412457f6 100644
--- a/src/util/scheduler.c
+++ b/src/util/scheduler.c
@@ -149,7 +149,7 @@ struct Task
149 * Set if we only wait for writing to a single FD, otherwise -1. 149 * Set if we only wait for writing to a single FD, otherwise -1.
150 */ 150 */
151 int write_fd; 151 int write_fd;
152 152
153 /** 153 /**
154 * Should the existence of this task in the queue be counted as 154 * Should the existence of this task in the queue be counted as
155 * reason to not shutdown the scheduler? 155 * reason to not shutdown the scheduler?
@@ -264,7 +264,7 @@ static void *scheduler_select_cls;
264 */ 264 */
265void 265void
266GNUNET_SCHEDULER_set_select (GNUNET_SCHEDULER_select new_select, 266GNUNET_SCHEDULER_set_select (GNUNET_SCHEDULER_select new_select,
267 void *new_select_cls) 267 void *new_select_cls)
268{ 268{
269 scheduler_select = new_select; 269 scheduler_select = new_select;
270 scheduler_select_cls = new_select_cls; 270 scheduler_select_cls = new_select_cls;
@@ -308,15 +308,26 @@ is_pending (GNUNET_SCHEDULER_TaskIdentifier id)
308 min = -1; /* maximum value */ 308 min = -1; /* maximum value */
309 pos = pending; 309 pos = pending;
310 while (pos != NULL) 310 while (pos != NULL)
311 { 311 {
312 if (pos->id == id) 312 if (pos->id == id)
313 return GNUNET_YES; 313 return GNUNET_YES;
314 if (pos->id < min) 314 if (pos->id < min)
315 min = pos->id; 315 min = pos->id;
316 pos = pos->next; 316 pos = pos->next;
317 } 317 }
318 pos = pending_timeout; 318 pos = pending_timeout;
319 while (pos != NULL) 319 while (pos != NULL)
320 {
321 if (pos->id == id)
322 return GNUNET_YES;
323 if (pos->id < min)
324 min = pos->id;
325 pos = pos->next;
326 }
327 for (p = 0; p < GNUNET_SCHEDULER_PRIORITY_COUNT; p++)
328 {
329 pos = ready[p];
330 while (pos != NULL)
320 { 331 {
321 if (pos->id == id) 332 if (pos->id == id)
322 return GNUNET_YES; 333 return GNUNET_YES;
@@ -324,18 +335,7 @@ is_pending (GNUNET_SCHEDULER_TaskIdentifier id)
324 min = pos->id; 335 min = pos->id;
325 pos = pos->next; 336 pos = pos->next;
326 } 337 }
327 for (p = 0; p < GNUNET_SCHEDULER_PRIORITY_COUNT; p++) 338 }
328 {
329 pos = ready[p];
330 while (pos != NULL)
331 {
332 if (pos->id == id)
333 return GNUNET_YES;
334 if (pos->id < min)
335 min = pos->id;
336 pos = pos->next;
337 }
338 }
339 lowest_pending_id = min; 339 lowest_pending_id = min;
340 return GNUNET_NO; 340 return GNUNET_NO;
341} 341}
@@ -359,41 +359,41 @@ update_sets (struct GNUNET_NETWORK_FDSet *rs,
359 359
360 now = GNUNET_TIME_absolute_get (); 360 now = GNUNET_TIME_absolute_get ();
361 pos = pending_timeout; 361 pos = pending_timeout;
362 if (pos != NULL) 362 if (pos != NULL)
363 { 363 {
364 to = GNUNET_TIME_absolute_get_difference (now, pos->timeout); 364 to = GNUNET_TIME_absolute_get_difference (now, pos->timeout);
365 if (timeout->rel_value > to.rel_value) 365 if (timeout->rel_value > to.rel_value)
366 *timeout = to; 366 *timeout = to;
367 if (pos->reason != 0) 367 if (pos->reason != 0)
368 *timeout = GNUNET_TIME_UNIT_ZERO; 368 *timeout = GNUNET_TIME_UNIT_ZERO;
369 } 369 }
370 pos = pending; 370 pos = pending;
371 while (pos != NULL) 371 while (pos != NULL)
372 {
373 if ((pos->prereq_id != GNUNET_SCHEDULER_NO_TASK) &&
374 (GNUNET_YES == is_pending (pos->prereq_id)))
372 { 375 {
373 if ((pos->prereq_id != GNUNET_SCHEDULER_NO_TASK) &&
374 (GNUNET_YES == is_pending (pos->prereq_id)))
375 {
376 pos = pos->next;
377 continue;
378 }
379 if (pos->timeout.abs_value != GNUNET_TIME_UNIT_FOREVER_ABS.abs_value)
380 {
381 to = GNUNET_TIME_absolute_get_difference (now, pos->timeout);
382 if (timeout->rel_value > to.rel_value)
383 *timeout = to;
384 }
385 if (pos->read_fd != -1)
386 GNUNET_NETWORK_fdset_set_native (rs, pos->read_fd);
387 if (pos->write_fd != -1)
388 GNUNET_NETWORK_fdset_set_native (ws, pos->write_fd);
389 if (pos->read_set != NULL)
390 GNUNET_NETWORK_fdset_add (rs, pos->read_set);
391 if (pos->write_set != NULL)
392 GNUNET_NETWORK_fdset_add (ws, pos->write_set);
393 if (pos->reason != 0)
394 *timeout = GNUNET_TIME_UNIT_ZERO;
395 pos = pos->next; 376 pos = pos->next;
377 continue;
378 }
379 if (pos->timeout.abs_value != GNUNET_TIME_UNIT_FOREVER_ABS.abs_value)
380 {
381 to = GNUNET_TIME_absolute_get_difference (now, pos->timeout);
382 if (timeout->rel_value > to.rel_value)
383 *timeout = to;
396 } 384 }
385 if (pos->read_fd != -1)
386 GNUNET_NETWORK_fdset_set_native (rs, pos->read_fd);
387 if (pos->write_fd != -1)
388 GNUNET_NETWORK_fdset_set_native (ws, pos->write_fd);
389 if (pos->read_set != NULL)
390 GNUNET_NETWORK_fdset_add (rs, pos->read_set);
391 if (pos->write_set != NULL)
392 GNUNET_NETWORK_fdset_add (ws, pos->write_set);
393 if (pos->reason != 0)
394 *timeout = GNUNET_TIME_UNIT_ZERO;
395 pos = pos->next;
396 }
397} 397}
398 398
399 399
@@ -410,15 +410,15 @@ static int
410set_overlaps (const struct GNUNET_NETWORK_FDSet *ready, 410set_overlaps (const struct GNUNET_NETWORK_FDSet *ready,
411 struct GNUNET_NETWORK_FDSet *want) 411 struct GNUNET_NETWORK_FDSet *want)
412{ 412{
413 if ( (NULL == want) || (NULL == ready) ) 413 if ((NULL == want) || (NULL == ready))
414 return GNUNET_NO; 414 return GNUNET_NO;
415 if (GNUNET_NETWORK_fdset_overlap (ready, want)) 415 if (GNUNET_NETWORK_fdset_overlap (ready, want))
416 { 416 {
417 /* copy all over (yes, there maybe unrelated bits, 417 /* copy all over (yes, there maybe unrelated bits,
418 but this should not hurt well-written clients) */ 418 * but this should not hurt well-written clients) */
419 GNUNET_NETWORK_fdset_copy (want, ready); 419 GNUNET_NETWORK_fdset_copy (want, ready);
420 return GNUNET_YES; 420 return GNUNET_YES;
421 } 421 }
422 return GNUNET_NO; 422 return GNUNET_NO;
423} 423}
424 424
@@ -444,27 +444,27 @@ is_ready (struct Task *task,
444 reason = task->reason; 444 reason = task->reason;
445 if (now.abs_value >= task->timeout.abs_value) 445 if (now.abs_value >= task->timeout.abs_value)
446 reason |= GNUNET_SCHEDULER_REASON_TIMEOUT; 446 reason |= GNUNET_SCHEDULER_REASON_TIMEOUT;
447 if ( (0 == (reason & GNUNET_SCHEDULER_REASON_READ_READY)) && 447 if ((0 == (reason & GNUNET_SCHEDULER_REASON_READ_READY)) &&
448 ( ( (task->read_fd != -1) && 448 (((task->read_fd != -1) &&
449 (GNUNET_YES == GNUNET_NETWORK_fdset_test_native (rs, task->read_fd)) ) || 449 (GNUNET_YES == GNUNET_NETWORK_fdset_test_native (rs, task->read_fd))) ||
450 (set_overlaps (rs, task->read_set) ) ) ) 450 (set_overlaps (rs, task->read_set))))
451 reason |= GNUNET_SCHEDULER_REASON_READ_READY; 451 reason |= GNUNET_SCHEDULER_REASON_READ_READY;
452 if ((0 == (reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) && 452 if ((0 == (reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) &&
453 ( ( (task->write_fd != -1) && 453 (((task->write_fd != -1) &&
454 (GNUNET_YES == GNUNET_NETWORK_fdset_test_native (ws, task->write_fd)) ) || 454 (GNUNET_YES == GNUNET_NETWORK_fdset_test_native (ws, task->write_fd)))
455 (set_overlaps (ws, task->write_set) ) ) ) 455 || (set_overlaps (ws, task->write_set))))
456 reason |= GNUNET_SCHEDULER_REASON_WRITE_READY; 456 reason |= GNUNET_SCHEDULER_REASON_WRITE_READY;
457 if (reason == 0) 457 if (reason == 0)
458 return GNUNET_NO; /* not ready */ 458 return GNUNET_NO; /* not ready */
459 if (task->prereq_id != GNUNET_SCHEDULER_NO_TASK) 459 if (task->prereq_id != GNUNET_SCHEDULER_NO_TASK)
460 {
461 if (GNUNET_YES == is_pending (task->prereq_id))
460 { 462 {
461 if (GNUNET_YES == is_pending (task->prereq_id)) 463 task->reason = reason;
462 { 464 return GNUNET_NO; /* prereq waiting */
463 task->reason = reason;
464 return GNUNET_NO; /* prereq waiting */
465 }
466 reason |= GNUNET_SCHEDULER_REASON_PREREQ_DONE;
467 } 465 }
466 reason |= GNUNET_SCHEDULER_REASON_PREREQ_DONE;
467 }
468 task->reason = reason; 468 task->reason = reason;
469 return GNUNET_YES; 469 return GNUNET_YES;
470} 470}
@@ -479,6 +479,7 @@ static void
479queue_ready_task (struct Task *task) 479queue_ready_task (struct Task *task)
480{ 480{
481 enum GNUNET_SCHEDULER_Priority p = task->priority; 481 enum GNUNET_SCHEDULER_Priority p = task->priority;
482
482 if (0 != (task->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) 483 if (0 != (task->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
483 p = GNUNET_SCHEDULER_PRIORITY_SHUTDOWN; 484 p = GNUNET_SCHEDULER_PRIORITY_SHUTDOWN;
484 task->next = ready[check_priority (p)]; 485 task->next = ready[check_priority (p)];
@@ -507,40 +508,40 @@ check_ready (const struct GNUNET_NETWORK_FDSet *rs,
507 prev = NULL; 508 prev = NULL;
508 pos = pending_timeout; 509 pos = pending_timeout;
509 while (pos != NULL) 510 while (pos != NULL)
510 { 511 {
511 next = pos->next; 512 next = pos->next;
512 if (now.abs_value >= pos->timeout.abs_value) 513 if (now.abs_value >= pos->timeout.abs_value)
513 pos->reason |= GNUNET_SCHEDULER_REASON_TIMEOUT; 514 pos->reason |= GNUNET_SCHEDULER_REASON_TIMEOUT;
514 if (0 == pos->reason) 515 if (0 == pos->reason)
515 break; 516 break;
516 pending_timeout = next; 517 pending_timeout = next;
517 if (pending_timeout_last == pos) 518 if (pending_timeout_last == pos)
518 pending_timeout_last = NULL; 519 pending_timeout_last = NULL;
519 queue_ready_task (pos); 520 queue_ready_task (pos);
520 pos = next; 521 pos = next;
521 } 522 }
522 pos = pending; 523 pos = pending;
523 while (pos != NULL) 524 while (pos != NULL)
524 { 525 {
525#if DEBUG_TASKS 526#if DEBUG_TASKS
526 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 527 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
527 "Checking readiness of task: %llu / %p\n", 528 "Checking readiness of task: %llu / %p\n",
528 pos->id, pos->callback_cls); 529 pos->id, pos->callback_cls);
529#endif 530#endif
530 next = pos->next; 531 next = pos->next;
531 if (GNUNET_YES == is_ready (pos, now, rs, ws)) 532 if (GNUNET_YES == is_ready (pos, now, rs, ws))
532 { 533 {
533 if (prev == NULL) 534 if (prev == NULL)
534 pending = next; 535 pending = next;
535 else 536 else
536 prev->next = next; 537 prev->next = next;
537 queue_ready_task (pos); 538 queue_ready_task (pos);
538 pos = next;
539 continue;
540 }
541 prev = pos;
542 pos = next; 539 pos = next;
540 continue;
543 } 541 }
542 prev = pos;
543 pos = next;
544 }
544} 545}
545 546
546 547
@@ -559,34 +560,34 @@ GNUNET_SCHEDULER_shutdown ()
559 560
560 pos = pending_timeout; 561 pos = pending_timeout;
561 while (pos != NULL) 562 while (pos != NULL)
562 { 563 {
563 pos->reason |= GNUNET_SCHEDULER_REASON_SHUTDOWN; 564 pos->reason |= GNUNET_SCHEDULER_REASON_SHUTDOWN;
564 /* we don't move the task into the ready queue yet; check_ready 565 /* we don't move the task into the ready queue yet; check_ready
565 will do that later, possibly adding additional 566 * will do that later, possibly adding additional
566 readiness-factors */ 567 * readiness-factors */
567 pos = pos->next; 568 pos = pos->next;
568 } 569 }
569 pos = pending; 570 pos = pending;
570 while (pos != NULL) 571 while (pos != NULL)
572 {
573 pos->reason |= GNUNET_SCHEDULER_REASON_SHUTDOWN;
574 /* we don't move the task into the ready queue yet; check_ready
575 * will do that later, possibly adding additional
576 * readiness-factors */
577 pos = pos->next;
578 }
579 for (i = 0; i < GNUNET_SCHEDULER_PRIORITY_COUNT; i++)
580 {
581 pos = ready[i];
582 while (pos != NULL)
571 { 583 {
572 pos->reason |= GNUNET_SCHEDULER_REASON_SHUTDOWN; 584 pos->reason |= GNUNET_SCHEDULER_REASON_SHUTDOWN;
573 /* we don't move the task into the ready queue yet; check_ready 585 /* we don't move the task into the ready queue yet; check_ready
574 will do that later, possibly adding additional 586 * will do that later, possibly adding additional
575 readiness-factors */ 587 * readiness-factors */
576 pos = pos->next; 588 pos = pos->next;
577 } 589 }
578 for (i=0;i<GNUNET_SCHEDULER_PRIORITY_COUNT;i++) 590 }
579 {
580 pos = ready[i];
581 while (pos != NULL)
582 {
583 pos->reason |= GNUNET_SCHEDULER_REASON_SHUTDOWN;
584 /* we don't move the task into the ready queue yet; check_ready
585 will do that later, possibly adding additional
586 readiness-factors */
587 pos = pos->next;
588 }
589 }
590} 591}
591 592
592 593
@@ -620,8 +621,7 @@ destroy_task (struct Task *t)
620 * @param ws FDs ready for writing 621 * @param ws FDs ready for writing
621 */ 622 */
622static void 623static void
623run_ready (struct GNUNET_NETWORK_FDSet *rs, 624run_ready (struct GNUNET_NETWORK_FDSet *rs, struct GNUNET_NETWORK_FDSet *ws)
624 struct GNUNET_NETWORK_FDSet *ws)
625{ 625{
626 enum GNUNET_SCHEDULER_Priority p; 626 enum GNUNET_SCHEDULER_Priority p;
627 struct Task *pos; 627 struct Task *pos;
@@ -629,74 +629,72 @@ run_ready (struct GNUNET_NETWORK_FDSet *rs,
629 629
630 max_priority_added = GNUNET_SCHEDULER_PRIORITY_KEEP; 630 max_priority_added = GNUNET_SCHEDULER_PRIORITY_KEEP;
631 do 631 do
632 {
633 if (ready_count == 0)
634 return;
635 GNUNET_assert (ready[GNUNET_SCHEDULER_PRIORITY_KEEP] == NULL);
636 /* yes, p>0 is correct, 0 is "KEEP" which should
637 * always be an empty queue (see assertion)! */
638 for (p = GNUNET_SCHEDULER_PRIORITY_COUNT - 1; p > 0; p--)
639 {
640 pos = ready[p];
641 if (pos != NULL)
642 break;
643 }
644 GNUNET_assert (pos != NULL); /* ready_count wrong? */
645 ready[p] = pos->next;
646 ready_count--;
647 if (current_priority != pos->priority)
632 { 648 {
633 if (ready_count == 0) 649 current_priority = pos->priority;
634 return; 650 (void) GNUNET_OS_set_process_priority (GNUNET_OS_process_current (),
635 GNUNET_assert (ready[GNUNET_SCHEDULER_PRIORITY_KEEP] == NULL); 651 pos->priority);
636 /* yes, p>0 is correct, 0 is "KEEP" which should 652 }
637 always be an empty queue (see assertion)! */ 653 current_lifeness = pos->lifeness;
638 for (p = GNUNET_SCHEDULER_PRIORITY_COUNT - 1; p > 0; p--) 654 active_task = pos;
639 {
640 pos = ready[p];
641 if (pos != NULL)
642 break;
643 }
644 GNUNET_assert (pos != NULL); /* ready_count wrong? */
645 ready[p] = pos->next;
646 ready_count--;
647 if (current_priority != pos->priority)
648 {
649 current_priority = pos->priority;
650 (void) GNUNET_OS_set_process_priority (GNUNET_OS_process_current (),
651 pos->priority);
652 }
653 current_lifeness = pos->lifeness;
654 active_task = pos;
655#if PROFILE_DELAYS 655#if PROFILE_DELAYS
656 if (GNUNET_TIME_absolute_get_duration (pos->start_time).rel_value > 656 if (GNUNET_TIME_absolute_get_duration (pos->start_time).rel_value >
657 DELAY_THRESHOLD.rel_value) 657 DELAY_THRESHOLD.rel_value)
658 { 658 {
659 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 659 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
660 "Task %llu took %llums to be scheduled\n", 660 "Task %llu took %llums to be scheduled\n",
661 pos->id, 661 pos->id,
662 (unsigned long long) GNUNET_TIME_absolute_get_duration (pos->start_time).rel_value); 662 (unsigned long long)
663 } 663 GNUNET_TIME_absolute_get_duration
664 (pos->start_time).rel_value);
665 }
664#endif 666#endif
665 tc.reason = pos->reason; 667 tc.reason = pos->reason;
666 tc.read_ready = (pos->read_set == NULL) ? rs : pos->read_set; 668 tc.read_ready = (pos->read_set == NULL) ? rs : pos->read_set;
667 if ( (pos->read_fd != -1) && 669 if ((pos->read_fd != -1) &&
668 (0 != (pos->reason & GNUNET_SCHEDULER_REASON_READ_READY)) ) 670 (0 != (pos->reason & GNUNET_SCHEDULER_REASON_READ_READY)))
669 GNUNET_NETWORK_fdset_set_native (rs, 671 GNUNET_NETWORK_fdset_set_native (rs, pos->read_fd);
670 pos->read_fd); 672 tc.write_ready = (pos->write_set == NULL) ? ws : pos->write_set;
671 tc.write_ready = (pos->write_set == NULL) ? ws : pos->write_set; 673 if ((pos->write_fd != -1) &&
672 if ( (pos->write_fd != -1) && 674 (0 != (pos->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)))
673 (0 != (pos->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) ) 675 GNUNET_NETWORK_fdset_set_native (ws, pos->write_fd);
674 GNUNET_NETWORK_fdset_set_native (ws, 676 if (((tc.reason & GNUNET_SCHEDULER_REASON_WRITE_READY) != 0) &&
675 pos->write_fd); 677 (pos->write_fd != -1) &&
676 if ( ( (tc.reason & GNUNET_SCHEDULER_REASON_WRITE_READY) != 0) && 678 (!GNUNET_NETWORK_fdset_test_native (ws, pos->write_fd)))
677 (pos->write_fd != -1) && 679 abort (); // added to ready in previous select loop!
678 (! GNUNET_NETWORK_fdset_test_native (ws,
679 pos->write_fd)))
680 abort (); // added to ready in previous select loop!
681#if DEBUG_TASKS 680#if DEBUG_TASKS
682 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 681 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
683 "Running task: %llu / %p\n", pos->id, pos->callback_cls); 682 "Running task: %llu / %p\n", pos->id, pos->callback_cls);
684#endif 683#endif
685 pos->callback (pos->callback_cls, &tc); 684 pos->callback (pos->callback_cls, &tc);
686#if EXECINFO 685#if EXECINFO
687 int i; 686 int i;
688 for (i=0;i<pos->num_backtrace_strings;i++) 687
689 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 688 for (i = 0; i < pos->num_backtrace_strings; i++)
690 "Task %llu trace %d: %s\n", 689 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
691 pos->id, 690 "Task %llu trace %d: %s\n",
692 i, 691 pos->id, i, pos->backtrace_strings[i]);
693 pos->backtrace_strings[i]);
694#endif 692#endif
695 active_task = NULL; 693 active_task = NULL;
696 destroy_task (pos); 694 destroy_task (pos);
697 tasks_run++; 695 tasks_run++;
698 } 696 }
699 while ( (pending == NULL) || (p >= max_priority_added) ); 697 while ((pending == NULL) || (p >= max_priority_added));
700} 698}
701 699
702/** 700/**
@@ -721,11 +719,11 @@ static void
721sighandler_shutdown () 719sighandler_shutdown ()
722{ 720{
723 static char c; 721 static char c;
724 int old_errno = errno; /* backup errno */ 722 int old_errno = errno; /* backup errno */
725 723
726 GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle 724 GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle
727 (shutdown_pipe_handle, GNUNET_DISK_PIPE_END_WRITE), &c, 725 (shutdown_pipe_handle, GNUNET_DISK_PIPE_END_WRITE),
728 sizeof (c)); 726 &c, sizeof (c));
729 errno = old_errno; 727 errno = old_errno;
730} 728}
731 729
@@ -738,9 +736,10 @@ sighandler_shutdown ()
738 * GNUNET_NO to exit 736 * GNUNET_NO to exit
739 */ 737 */
740static int 738static int
741check_lifeness() 739check_lifeness ()
742{ 740{
743 struct Task *t; 741 struct Task *t;
742
744 if (ready_count > 0) 743 if (ready_count > 0)
745 return GNUNET_OK; 744 return GNUNET_OK;
746 for (t = pending; NULL != t; t = t->next) 745 for (t = pending; NULL != t; t = t->next)
@@ -748,12 +747,12 @@ check_lifeness()
748 return GNUNET_OK; 747 return GNUNET_OK;
749 for (t = pending_timeout; NULL != t; t = t->next) 748 for (t = pending_timeout; NULL != t; t = t->next)
750 if (t->lifeness == GNUNET_YES) 749 if (t->lifeness == GNUNET_YES)
751 return GNUNET_OK;
752 if ( (NULL != pending) || (NULL != pending_timeout) )
753 {
754 GNUNET_SCHEDULER_shutdown ();
755 return GNUNET_OK; 750 return GNUNET_OK;
756 } 751 if ((NULL != pending) || (NULL != pending_timeout))
752 {
753 GNUNET_SCHEDULER_shutdown ();
754 return GNUNET_OK;
755 }
757 return GNUNET_NO; 756 return GNUNET_NO;
758} 757}
759 758
@@ -781,6 +780,7 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_Task task, void *task_cls)
781 int ret; 780 int ret;
782 struct GNUNET_SIGNAL_Context *shc_int; 781 struct GNUNET_SIGNAL_Context *shc_int;
783 struct GNUNET_SIGNAL_Context *shc_term; 782 struct GNUNET_SIGNAL_Context *shc_term;
783
784#ifndef MINGW 784#ifndef MINGW
785 struct GNUNET_SIGNAL_Context *shc_quit; 785 struct GNUNET_SIGNAL_Context *shc_quit;
786 struct GNUNET_SIGNAL_Context *shc_hup; 786 struct GNUNET_SIGNAL_Context *shc_hup;
@@ -795,9 +795,10 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_Task task, void *task_cls)
795 rs = GNUNET_NETWORK_fdset_create (); 795 rs = GNUNET_NETWORK_fdset_create ();
796 ws = GNUNET_NETWORK_fdset_create (); 796 ws = GNUNET_NETWORK_fdset_create ();
797 GNUNET_assert (shutdown_pipe_handle == NULL); 797 GNUNET_assert (shutdown_pipe_handle == NULL);
798 shutdown_pipe_handle = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO); 798 shutdown_pipe_handle = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO);
799 GNUNET_assert (shutdown_pipe_handle != NULL); 799 GNUNET_assert (shutdown_pipe_handle != NULL);
800 pr = GNUNET_DISK_pipe_handle (shutdown_pipe_handle, GNUNET_DISK_PIPE_END_READ); 800 pr = GNUNET_DISK_pipe_handle (shutdown_pipe_handle,
801 GNUNET_DISK_PIPE_END_READ);
801 GNUNET_assert (pr != NULL); 802 GNUNET_assert (pr != NULL);
802 shc_int = GNUNET_SIGNAL_handler_install (SIGINT, &sighandler_shutdown); 803 shc_int = GNUNET_SIGNAL_handler_install (SIGINT, &sighandler_shutdown);
803 shc_term = GNUNET_SIGNAL_handler_install (SIGTERM, &sighandler_shutdown); 804 shc_term = GNUNET_SIGNAL_handler_install (SIGTERM, &sighandler_shutdown);
@@ -809,79 +810,77 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_Task task, void *task_cls)
809 current_priority = GNUNET_SCHEDULER_PRIORITY_DEFAULT; 810 current_priority = GNUNET_SCHEDULER_PRIORITY_DEFAULT;
810 current_lifeness = GNUNET_YES; 811 current_lifeness = GNUNET_YES;
811 GNUNET_SCHEDULER_add_continuation (task, 812 GNUNET_SCHEDULER_add_continuation (task,
812 task_cls, 813 task_cls, GNUNET_SCHEDULER_REASON_STARTUP);
813 GNUNET_SCHEDULER_REASON_STARTUP);
814#if ENABLE_WINDOWS_WORKAROUNDS 814#if ENABLE_WINDOWS_WORKAROUNDS
815 active_task = (void*) (long) -1; /* force passing of sanity check */ 815 active_task = (void *) (long) -1; /* force passing of sanity check */
816 GNUNET_SCHEDULER_add_now_with_lifeness (GNUNET_NO, 816 GNUNET_SCHEDULER_add_now_with_lifeness (GNUNET_NO,
817 &GNUNET_OS_install_parent_control_handler, 817 &GNUNET_OS_install_parent_control_handler,
818 NULL); 818 NULL);
819 active_task = NULL; 819 active_task = NULL;
820#endif 820#endif
821 last_tr = 0; 821 last_tr = 0;
822 busy_wait_warning = 0; 822 busy_wait_warning = 0;
823 while (GNUNET_OK == check_lifeness ()) 823 while (GNUNET_OK == check_lifeness ())
824 {
825 GNUNET_NETWORK_fdset_zero (rs);
826 GNUNET_NETWORK_fdset_zero (ws);
827 timeout = GNUNET_TIME_UNIT_FOREVER_REL;
828 update_sets (rs, ws, &timeout);
829 GNUNET_NETWORK_fdset_handle_set (rs, pr);
830 if (ready_count > 0)
824 { 831 {
825 GNUNET_NETWORK_fdset_zero (rs); 832 /* no blocking, more work already ready! */
826 GNUNET_NETWORK_fdset_zero (ws); 833 timeout = GNUNET_TIME_UNIT_ZERO;
827 timeout = GNUNET_TIME_UNIT_FOREVER_REL; 834 }
828 update_sets (rs, ws, &timeout); 835 if (NULL == scheduler_select)
829 GNUNET_NETWORK_fdset_handle_set (rs, pr); 836 ret = GNUNET_NETWORK_socket_select (rs, ws, NULL, timeout);
830 if (ready_count > 0) 837 else
831 { 838 ret = scheduler_select (scheduler_select_cls, rs, ws, NULL, timeout);
832 /* no blocking, more work already ready! */ 839 if (ret == GNUNET_SYSERR)
833 timeout = GNUNET_TIME_UNIT_ZERO; 840 {
834 } 841 if (errno == EINTR)
835 if (NULL == scheduler_select) 842 continue;
836 ret = GNUNET_NETWORK_socket_select (rs, ws, NULL, timeout); 843
837 else 844 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "select");
838 ret = scheduler_select (scheduler_select_cls,
839 rs, ws, NULL,
840 timeout);
841 if (ret == GNUNET_SYSERR)
842 {
843 if (errno == EINTR)
844 continue;
845
846 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "select");
847#ifndef MINGW 845#ifndef MINGW
848#if USE_LSOF 846#if USE_LSOF
849 char lsof[512]; 847 char lsof[512];
850 snprintf (lsof, sizeof (lsof), "lsof -p %d", getpid()); 848
851 (void) close (1); 849 snprintf (lsof, sizeof (lsof), "lsof -p %d", getpid ());
852 (void) dup2 (2, 1); 850 (void) close (1);
853 if (0 != system (lsof)) 851 (void) dup2 (2, 1);
854 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "system"); 852 if (0 != system (lsof))
853 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "system");
855#endif 854#endif
856#endif 855#endif
857 abort (); 856 abort ();
858 break; 857 break;
859 } 858 }
860 if ((ret == 0) && (timeout.rel_value == 0) && (busy_wait_warning > 16)) 859 if ((ret == 0) && (timeout.rel_value == 0) && (busy_wait_warning > 16))
861 { 860 {
862 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 861 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
863 _("Looks like we're busy waiting...\n")); 862 _("Looks like we're busy waiting...\n"));
864 sleep (1); /* mitigate */ 863 sleep (1); /* mitigate */
865 }
866 check_ready (rs, ws);
867 run_ready (rs, ws);
868 if (GNUNET_NETWORK_fdset_handle_isset (rs, pr))
869 {
870 /* consume the signal */
871 GNUNET_DISK_file_read (pr, &c, sizeof (c));
872 /* mark all active tasks as ready due to shutdown */
873 GNUNET_SCHEDULER_shutdown ();
874 }
875 if (last_tr == tasks_run)
876 {
877 busy_wait_warning++;
878 }
879 else
880 {
881 last_tr = tasks_run;
882 busy_wait_warning = 0;
883 }
884 } 864 }
865 check_ready (rs, ws);
866 run_ready (rs, ws);
867 if (GNUNET_NETWORK_fdset_handle_isset (rs, pr))
868 {
869 /* consume the signal */
870 GNUNET_DISK_file_read (pr, &c, sizeof (c));
871 /* mark all active tasks as ready due to shutdown */
872 GNUNET_SCHEDULER_shutdown ();
873 }
874 if (last_tr == tasks_run)
875 {
876 busy_wait_warning++;
877 }
878 else
879 {
880 last_tr = tasks_run;
881 busy_wait_warning = 0;
882 }
883 }
885 GNUNET_SIGNAL_handler_uninstall (shc_int); 884 GNUNET_SIGNAL_handler_uninstall (shc_int);
886 GNUNET_SIGNAL_handler_uninstall (shc_term); 885 GNUNET_SIGNAL_handler_uninstall (shc_term);
887#ifndef MINGW 886#ifndef MINGW
@@ -934,10 +933,10 @@ GNUNET_SCHEDULER_get_load (enum GNUNET_SCHEDULER_Priority p)
934 ret = 0; 933 ret = 0;
935 pos = ready[check_priority (p)]; 934 pos = ready[check_priority (p)];
936 while (pos != NULL) 935 while (pos != NULL)
937 { 936 {
938 pos = pos->next; 937 pos = pos->next;
939 ret++; 938 ret++;
940 } 939 }
941 return ret; 940 return ret;
942} 941}
943 942
@@ -963,73 +962,73 @@ GNUNET_SCHEDULER_cancel (GNUNET_SCHEDULER_TaskIdentifier task)
963 prev = NULL; 962 prev = NULL;
964 t = pending; 963 t = pending;
965 while (t != NULL) 964 while (t != NULL)
965 {
966 if (t->id == task)
967 break;
968 prev = t;
969 t = t->next;
970 }
971 if (t == NULL)
972 {
973 prev = NULL;
974 to = 1;
975 t = pending_timeout;
976 while (t != NULL)
966 { 977 {
967 if (t->id == task) 978 if (t->id == task)
968 break; 979 break;
969 prev = t; 980 prev = t;
970 t = t->next; 981 t = t->next;
971 } 982 }
972 if (t == NULL) 983 if (pending_timeout_last == t)
973 { 984 pending_timeout_last = NULL;
974 prev = NULL; 985 }
975 to = 1;
976 t = pending_timeout;
977 while (t != NULL)
978 {
979 if (t->id == task)
980 break;
981 prev = t;
982 t = t->next;
983 }
984 if (pending_timeout_last == t)
985 pending_timeout_last = NULL;
986 }
987 p = 0; 986 p = 0;
988 while (t == NULL) 987 while (t == NULL)
988 {
989 p++;
990 if (p >= GNUNET_SCHEDULER_PRIORITY_COUNT)
989 { 991 {
990 p++; 992 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
991 if (p >= GNUNET_SCHEDULER_PRIORITY_COUNT) 993 _("Attempt to cancel dead task %llu!\n"),
992 { 994 (unsigned long long) task);
993 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 995 GNUNET_assert (0);
994 _("Attempt to cancel dead task %llu!\n"),
995 (unsigned long long) task);
996 GNUNET_assert (0);
997 }
998 prev = NULL;
999 t = ready[p];
1000 while (t != NULL)
1001 {
1002 if (t->id == task)
1003 {
1004 ready_count--;
1005 break;
1006 }
1007 prev = t;
1008 t = t->next;
1009 }
1010 } 996 }
997 prev = NULL;
998 t = ready[p];
999 while (t != NULL)
1000 {
1001 if (t->id == task)
1002 {
1003 ready_count--;
1004 break;
1005 }
1006 prev = t;
1007 t = t->next;
1008 }
1009 }
1011 if (prev == NULL) 1010 if (prev == NULL)
1011 {
1012 if (p == 0)
1012 { 1013 {
1013 if (p == 0) 1014 if (to == 0)
1014 { 1015 {
1015 if (to == 0) 1016 pending = t->next;
1016 { 1017 }
1017 pending = t->next;
1018 }
1019 else
1020 {
1021 pending_timeout = t->next;
1022 }
1023 }
1024 else 1018 else
1025 { 1019 {
1026 ready[p] = t->next; 1020 pending_timeout = t->next;
1027 } 1021 }
1028 } 1022 }
1029 else 1023 else
1030 { 1024 {
1031 prev->next = t->next; 1025 ready[p] = t->next;
1032 } 1026 }
1027 }
1028 else
1029 {
1030 prev->next = t->next;
1031 }
1033 ret = t->callback_cls; 1032 ret = t->callback_cls;
1034#if DEBUG_TASKS 1033#if DEBUG_TASKS
1035 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1034 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1055,17 +1054,19 @@ GNUNET_SCHEDULER_add_continuation (GNUNET_SCHEDULER_Task task,
1055 enum GNUNET_SCHEDULER_Reason reason) 1054 enum GNUNET_SCHEDULER_Reason reason)
1056{ 1055{
1057 struct Task *t; 1056 struct Task *t;
1057
1058#if EXECINFO 1058#if EXECINFO
1059 void *backtrace_array[50]; 1059 void *backtrace_array[50];
1060#endif 1060#endif
1061 1061
1062 GNUNET_assert (NULL != task); 1062 GNUNET_assert (NULL != task);
1063 GNUNET_assert ( (active_task != NULL) || 1063 GNUNET_assert ((active_task != NULL) ||
1064 (reason == GNUNET_SCHEDULER_REASON_STARTUP) ); 1064 (reason == GNUNET_SCHEDULER_REASON_STARTUP));
1065 t = GNUNET_malloc (sizeof (struct Task)); 1065 t = GNUNET_malloc (sizeof (struct Task));
1066#if EXECINFO 1066#if EXECINFO
1067 t->num_backtrace_strings = backtrace(backtrace_array, 50); 1067 t->num_backtrace_strings = backtrace (backtrace_array, 50);
1068 t->backtrace_strings = backtrace_symbols(backtrace_array, t->num_backtrace_strings); 1068 t->backtrace_strings =
1069 backtrace_symbols (backtrace_array, t->num_backtrace_strings);
1069#endif 1070#endif
1070 t->read_fd = -1; 1071 t->read_fd = -1;
1071 t->write_fd = -1; 1072 t->write_fd = -1;
@@ -1080,8 +1081,7 @@ GNUNET_SCHEDULER_add_continuation (GNUNET_SCHEDULER_Task task,
1080 t->lifeness = current_lifeness; 1081 t->lifeness = current_lifeness;
1081#if DEBUG_TASKS 1082#if DEBUG_TASKS
1082 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1083 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1083 "Adding continuation task: %llu / %p\n", 1084 "Adding continuation task: %llu / %p\n", t->id, t->callback_cls);
1084 t->id, t->callback_cls);
1085#endif 1085#endif
1086 queue_ready_task (t); 1086 queue_ready_task (t);
1087} 1087}
@@ -1126,8 +1126,7 @@ GNUNET_SCHEDULER_add_after (GNUNET_SCHEDULER_TaskIdentifier prerequisite_task,
1126 */ 1126 */
1127GNUNET_SCHEDULER_TaskIdentifier 1127GNUNET_SCHEDULER_TaskIdentifier
1128GNUNET_SCHEDULER_add_with_priority (enum GNUNET_SCHEDULER_Priority prio, 1128GNUNET_SCHEDULER_add_with_priority (enum GNUNET_SCHEDULER_Priority prio,
1129 GNUNET_SCHEDULER_Task task, 1129 GNUNET_SCHEDULER_Task task, void *task_cls)
1130 void *task_cls)
1131{ 1130{
1132 return GNUNET_SCHEDULER_add_select (prio, 1131 return GNUNET_SCHEDULER_add_select (prio,
1133 GNUNET_SCHEDULER_NO_TASK, 1132 GNUNET_SCHEDULER_NO_TASK,
@@ -1158,6 +1157,7 @@ GNUNET_SCHEDULER_add_delayed (struct GNUNET_TIME_Relative delay,
1158 struct Task *t; 1157 struct Task *t;
1159 struct Task *pos; 1158 struct Task *pos;
1160 struct Task *prev; 1159 struct Task *prev;
1160
1161#if EXECINFO 1161#if EXECINFO
1162 void *backtrace_array[MAX_TRACE_DEPTH]; 1162 void *backtrace_array[MAX_TRACE_DEPTH];
1163#endif 1163#endif
@@ -1168,8 +1168,9 @@ GNUNET_SCHEDULER_add_delayed (struct GNUNET_TIME_Relative delay,
1168 t->callback = task; 1168 t->callback = task;
1169 t->callback_cls = task_cls; 1169 t->callback_cls = task_cls;
1170#if EXECINFO 1170#if EXECINFO
1171 t->num_backtrace_strings = backtrace(backtrace_array, MAX_TRACE_DEPTH); 1171 t->num_backtrace_strings = backtrace (backtrace_array, MAX_TRACE_DEPTH);
1172 t->backtrace_strings = backtrace_symbols(backtrace_array, t->num_backtrace_strings); 1172 t->backtrace_strings =
1173 backtrace_symbols (backtrace_array, t->num_backtrace_strings);
1173#endif 1174#endif
1174 t->read_fd = -1; 1175 t->read_fd = -1;
1175 t->write_fd = -1; 1176 t->write_fd = -1;
@@ -1181,27 +1182,27 @@ GNUNET_SCHEDULER_add_delayed (struct GNUNET_TIME_Relative delay,
1181 t->priority = current_priority; 1182 t->priority = current_priority;
1182 t->lifeness = current_lifeness; 1183 t->lifeness = current_lifeness;
1183 /* try tail first (optimization in case we are 1184 /* try tail first (optimization in case we are
1184 appending to a long list of tasks with timeouts) */ 1185 * appending to a long list of tasks with timeouts) */
1185 prev = pending_timeout_last; 1186 prev = pending_timeout_last;
1186 if (prev != NULL) 1187 if (prev != NULL)
1187 { 1188 {
1188 if (prev->timeout.abs_value > t->timeout.abs_value) 1189 if (prev->timeout.abs_value > t->timeout.abs_value)
1189 prev = NULL; 1190 prev = NULL;
1190 else 1191 else
1191 pos = prev->next; /* heuristic success! */ 1192 pos = prev->next; /* heuristic success! */
1192 } 1193 }
1193 if (prev == NULL) 1194 if (prev == NULL)
1194 { 1195 {
1195 /* heuristic failed, do traversal of timeout list */ 1196 /* heuristic failed, do traversal of timeout list */
1196 pos = pending_timeout; 1197 pos = pending_timeout;
1197 } 1198 }
1198 while ( (pos != NULL) && 1199 while ((pos != NULL) &&
1199 ( (pos->timeout.abs_value <= t->timeout.abs_value) || 1200 ((pos->timeout.abs_value <= t->timeout.abs_value) ||
1200 (pos->reason != 0) ) ) 1201 (pos->reason != 0)))
1201 { 1202 {
1202 prev = pos; 1203 prev = pos;
1203 pos = pos->next; 1204 pos = pos->next;
1204 } 1205 }
1205 if (prev == NULL) 1206 if (prev == NULL)
1206 pending_timeout = t; 1207 pending_timeout = t;
1207 else 1208 else
@@ -1217,12 +1218,9 @@ GNUNET_SCHEDULER_add_delayed (struct GNUNET_TIME_Relative delay,
1217#if EXECINFO 1218#if EXECINFO
1218 int i; 1219 int i;
1219 1220
1220 for (i=0;i<t->num_backtrace_strings;i++) 1221 for (i = 0; i < t->num_backtrace_strings; i++)
1221 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1222 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1222 "Task %llu trace %d: %s\n", 1223 "Task %llu trace %d: %s\n", t->id, i, t->backtrace_strings[i]);
1223 t->id,
1224 i,
1225 t->backtrace_strings[i]);
1226#endif 1224#endif
1227 return t->id; 1225 return t->id;
1228 1226
@@ -1246,12 +1244,11 @@ GNUNET_SCHEDULER_add_delayed (struct GNUNET_TIME_Relative delay,
1246 * only valid until "task" is started! 1244 * only valid until "task" is started!
1247 */ 1245 */
1248GNUNET_SCHEDULER_TaskIdentifier 1246GNUNET_SCHEDULER_TaskIdentifier
1249GNUNET_SCHEDULER_add_now (GNUNET_SCHEDULER_Task task, 1247GNUNET_SCHEDULER_add_now (GNUNET_SCHEDULER_Task task, void *task_cls)
1250 void *task_cls)
1251{ 1248{
1252 return GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_KEEP, 1249 return GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_KEEP,
1253 GNUNET_SCHEDULER_NO_TASK, 1250 GNUNET_SCHEDULER_NO_TASK,
1254 GNUNET_TIME_UNIT_ZERO, 1251 GNUNET_TIME_UNIT_ZERO,
1255 NULL, NULL, task, task_cls); 1252 NULL, NULL, task, task_cls);
1256} 1253}
1257 1254
@@ -1272,15 +1269,15 @@ GNUNET_SCHEDULER_add_now (GNUNET_SCHEDULER_Task task,
1272 */ 1269 */
1273GNUNET_SCHEDULER_TaskIdentifier 1270GNUNET_SCHEDULER_TaskIdentifier
1274GNUNET_SCHEDULER_add_now_with_lifeness (int lifeness, 1271GNUNET_SCHEDULER_add_now_with_lifeness (int lifeness,
1275 GNUNET_SCHEDULER_Task task, 1272 GNUNET_SCHEDULER_Task task,
1276 void *task_cls) 1273 void *task_cls)
1277{ 1274{
1278 GNUNET_SCHEDULER_TaskIdentifier ret; 1275 GNUNET_SCHEDULER_TaskIdentifier ret;
1279 1276
1280 ret = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_KEEP, 1277 ret = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_KEEP,
1281 GNUNET_SCHEDULER_NO_TASK, 1278 GNUNET_SCHEDULER_NO_TASK,
1282 GNUNET_TIME_UNIT_ZERO, 1279 GNUNET_TIME_UNIT_ZERO,
1283 NULL, NULL, task, task_cls); 1280 NULL, NULL, task, task_cls);
1284 GNUNET_assert (pending->id == ret); 1281 GNUNET_assert (pending->id == ret);
1285 pending->lifeness = lifeness; 1282 pending->lifeness = lifeness;
1286 return ret; 1283 return ret;
@@ -1318,11 +1315,10 @@ GNUNET_SCHEDULER_add_now_with_lifeness (int lifeness,
1318#ifndef MINGW 1315#ifndef MINGW
1319GNUNET_SCHEDULER_TaskIdentifier 1316GNUNET_SCHEDULER_TaskIdentifier
1320add_without_sets (struct GNUNET_TIME_Relative delay, 1317add_without_sets (struct GNUNET_TIME_Relative delay,
1321 int rfd, 1318 int rfd, int wfd, GNUNET_SCHEDULER_Task task, void *task_cls)
1322 int wfd,
1323 GNUNET_SCHEDULER_Task task, void *task_cls)
1324{ 1319{
1325 struct Task *t; 1320 struct Task *t;
1321
1326#if EXECINFO 1322#if EXECINFO
1327 void *backtrace_array[MAX_TRACE_DEPTH]; 1323 void *backtrace_array[MAX_TRACE_DEPTH];
1328#endif 1324#endif
@@ -1333,47 +1329,50 @@ add_without_sets (struct GNUNET_TIME_Relative delay,
1333 t->callback = task; 1329 t->callback = task;
1334 t->callback_cls = task_cls; 1330 t->callback_cls = task_cls;
1335#if EXECINFO 1331#if EXECINFO
1336 t->num_backtrace_strings = backtrace(backtrace_array, MAX_TRACE_DEPTH); 1332 t->num_backtrace_strings = backtrace (backtrace_array, MAX_TRACE_DEPTH);
1337 t->backtrace_strings = backtrace_symbols(backtrace_array, t->num_backtrace_strings); 1333 t->backtrace_strings =
1334 backtrace_symbols (backtrace_array, t->num_backtrace_strings);
1338#endif 1335#endif
1339#if DEBUG_FDS 1336#if DEBUG_FDS
1340 if (-1 != rfd) 1337 if (-1 != rfd)
1338 {
1339 int flags = fcntl (rfd, F_GETFD);
1340
1341 if (flags == -1 && errno == EBADF)
1341 { 1342 {
1342 int flags = fcntl(rfd, F_GETFD); 1343 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Got invalid file descriptor %d!\n",
1343 if (flags == -1 && errno == EBADF) 1344 rfd);
1344 {
1345 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Got invalid file descriptor %d!\n", rfd);
1346#if EXECINFO 1345#if EXECINFO
1347 int i; 1346 int i;
1348 1347
1349 for (i=0;i<t->num_backtrace_strings;i++) 1348 for (i = 0; i < t->num_backtrace_strings; i++)
1350 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1349 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1351 "Trace: %s\n", 1350 "Trace: %s\n", t->backtrace_strings[i]);
1352 t->backtrace_strings[i]);
1353#endif 1351#endif
1354 GNUNET_assert(0); 1352 GNUNET_assert (0);
1355 }
1356 } 1353 }
1354 }
1357 if (-1 != wfd) 1355 if (-1 != wfd)
1356 {
1357 int flags = fcntl (wfd, F_GETFD);
1358
1359 if (flags == -1 && errno == EBADF)
1358 { 1360 {
1359 int flags = fcntl(wfd, F_GETFD); 1361 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Got invalid file descriptor %d!\n",
1360 if (flags == -1 && errno == EBADF) 1362 wfd);
1361 {
1362 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Got invalid file descriptor %d!\n", wfd);
1363#if EXECINFO 1363#if EXECINFO
1364 int i; 1364 int i;
1365 1365
1366 for (i=0;i<t->num_backtrace_strings;i++) 1366 for (i = 0; i < t->num_backtrace_strings; i++)
1367 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1367 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1368 "Trace: %s\n", 1368 "Trace: %s\n", t->backtrace_strings[i]);
1369 t->backtrace_strings[i]);
1370#endif 1369#endif
1371 GNUNET_assert(0); 1370 GNUNET_assert (0);
1372 }
1373 } 1371 }
1372 }
1374#endif 1373#endif
1375 t->read_fd = rfd; 1374 t->read_fd = rfd;
1376 GNUNET_assert(wfd >= -1); 1375 GNUNET_assert (wfd >= -1);
1377 t->write_fd = wfd; 1376 t->write_fd = wfd;
1378 t->id = ++last_id; 1377 t->id = ++last_id;
1379#if PROFILE_DELAYS 1378#if PROFILE_DELAYS
@@ -1385,8 +1384,7 @@ add_without_sets (struct GNUNET_TIME_Relative delay,
1385 t->lifeness = current_lifeness; 1384 t->lifeness = current_lifeness;
1386 t->next = pending; 1385 t->next = pending;
1387 pending = t; 1386 pending = t;
1388 max_priority_added = GNUNET_MAX (max_priority_added, 1387 max_priority_added = GNUNET_MAX (max_priority_added, t->priority);
1389 t->priority);
1390#if DEBUG_TASKS 1388#if DEBUG_TASKS
1391 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1389 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1392 "Adding task: %llu / %p\n", t->id, t->callback_cls); 1390 "Adding task: %llu / %p\n", t->id, t->callback_cls);
@@ -1394,12 +1392,9 @@ add_without_sets (struct GNUNET_TIME_Relative delay,
1394#if EXECINFO 1392#if EXECINFO
1395 int i; 1393 int i;
1396 1394
1397 for (i=0;i<t->num_backtrace_strings;i++) 1395 for (i = 0; i < t->num_backtrace_strings; i++)
1398 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1396 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1399 "Task %llu trace %d: %s\n", 1397 "Task %llu trace %d: %s\n", t->id, i, t->backtrace_strings[i]);
1400 t->id,
1401 i,
1402 t->backtrace_strings[i]);
1403#endif 1398#endif
1404 return t->id; 1399 return t->id;
1405} 1400}
@@ -1425,7 +1420,7 @@ add_without_sets (struct GNUNET_TIME_Relative delay,
1425 */ 1420 */
1426GNUNET_SCHEDULER_TaskIdentifier 1421GNUNET_SCHEDULER_TaskIdentifier
1427GNUNET_SCHEDULER_add_read_net (struct GNUNET_TIME_Relative delay, 1422GNUNET_SCHEDULER_add_read_net (struct GNUNET_TIME_Relative delay,
1428 struct GNUNET_NETWORK_Handle * rfd, 1423 struct GNUNET_NETWORK_Handle *rfd,
1429 GNUNET_SCHEDULER_Task task, void *task_cls) 1424 GNUNET_SCHEDULER_Task task, void *task_cls)
1430{ 1425{
1431#if MINGW 1426#if MINGW
@@ -1442,10 +1437,7 @@ GNUNET_SCHEDULER_add_read_net (struct GNUNET_TIME_Relative delay,
1442 return ret; 1437 return ret;
1443#else 1438#else
1444 return add_without_sets (delay, 1439 return add_without_sets (delay,
1445 GNUNET_NETWORK_get_fd (rfd), 1440 GNUNET_NETWORK_get_fd (rfd), -1, task, task_cls);
1446 -1,
1447 task,
1448 task_cls);
1449#endif 1441#endif
1450} 1442}
1451 1443
@@ -1468,7 +1460,7 @@ GNUNET_SCHEDULER_add_read_net (struct GNUNET_TIME_Relative delay,
1468 */ 1460 */
1469GNUNET_SCHEDULER_TaskIdentifier 1461GNUNET_SCHEDULER_TaskIdentifier
1470GNUNET_SCHEDULER_add_write_net (struct GNUNET_TIME_Relative delay, 1462GNUNET_SCHEDULER_add_write_net (struct GNUNET_TIME_Relative delay,
1471 struct GNUNET_NETWORK_Handle * wfd, 1463 struct GNUNET_NETWORK_Handle *wfd,
1472 GNUNET_SCHEDULER_Task task, void *task_cls) 1464 GNUNET_SCHEDULER_Task task, void *task_cls)
1473{ 1465{
1474#if MINGW 1466#if MINGW
@@ -1484,12 +1476,9 @@ GNUNET_SCHEDULER_add_write_net (struct GNUNET_TIME_Relative delay,
1484 GNUNET_NETWORK_fdset_destroy (ws); 1476 GNUNET_NETWORK_fdset_destroy (ws);
1485 return ret; 1477 return ret;
1486#else 1478#else
1487 GNUNET_assert(GNUNET_NETWORK_get_fd(wfd) >= 0); 1479 GNUNET_assert (GNUNET_NETWORK_get_fd (wfd) >= 0);
1488 return add_without_sets (delay, 1480 return add_without_sets (delay,
1489 -1, 1481 -1, GNUNET_NETWORK_get_fd (wfd), task, task_cls);
1490 GNUNET_NETWORK_get_fd (wfd),
1491 task,
1492 task_cls);
1493#endif 1482#endif
1494} 1483}
1495 1484
@@ -1512,7 +1501,7 @@ GNUNET_SCHEDULER_add_write_net (struct GNUNET_TIME_Relative delay,
1512 */ 1501 */
1513GNUNET_SCHEDULER_TaskIdentifier 1502GNUNET_SCHEDULER_TaskIdentifier
1514GNUNET_SCHEDULER_add_read_file (struct GNUNET_TIME_Relative delay, 1503GNUNET_SCHEDULER_add_read_file (struct GNUNET_TIME_Relative delay,
1515 const struct GNUNET_DISK_FileHandle * rfd, 1504 const struct GNUNET_DISK_FileHandle *rfd,
1516 GNUNET_SCHEDULER_Task task, void *task_cls) 1505 GNUNET_SCHEDULER_Task task, void *task_cls)
1517{ 1506{
1518#if MINGW 1507#if MINGW
@@ -1531,11 +1520,7 @@ GNUNET_SCHEDULER_add_read_file (struct GNUNET_TIME_Relative delay,
1531 int fd; 1520 int fd;
1532 1521
1533 GNUNET_DISK_internal_file_handle_ (rfd, &fd, sizeof (int)); 1522 GNUNET_DISK_internal_file_handle_ (rfd, &fd, sizeof (int));
1534 return add_without_sets (delay, 1523 return add_without_sets (delay, fd, -1, task, task_cls);
1535 fd,
1536 -1,
1537 task,
1538 task_cls);
1539 1524
1540#endif 1525#endif
1541} 1526}
@@ -1559,7 +1544,7 @@ GNUNET_SCHEDULER_add_read_file (struct GNUNET_TIME_Relative delay,
1559 */ 1544 */
1560GNUNET_SCHEDULER_TaskIdentifier 1545GNUNET_SCHEDULER_TaskIdentifier
1561GNUNET_SCHEDULER_add_write_file (struct GNUNET_TIME_Relative delay, 1546GNUNET_SCHEDULER_add_write_file (struct GNUNET_TIME_Relative delay,
1562 const struct GNUNET_DISK_FileHandle * wfd, 1547 const struct GNUNET_DISK_FileHandle *wfd,
1563 GNUNET_SCHEDULER_Task task, void *task_cls) 1548 GNUNET_SCHEDULER_Task task, void *task_cls)
1564{ 1549{
1565#if MINGW 1550#if MINGW
@@ -1578,12 +1563,8 @@ GNUNET_SCHEDULER_add_write_file (struct GNUNET_TIME_Relative delay,
1578 int fd; 1563 int fd;
1579 1564
1580 GNUNET_DISK_internal_file_handle_ (wfd, &fd, sizeof (int)); 1565 GNUNET_DISK_internal_file_handle_ (wfd, &fd, sizeof (int));
1581 GNUNET_assert(fd >= 0); 1566 GNUNET_assert (fd >= 0);
1582 return add_without_sets (delay, 1567 return add_without_sets (delay, -1, fd, task, task_cls);
1583 -1,
1584 fd,
1585 task,
1586 task_cls);
1587 1568
1588#endif 1569#endif
1589} 1570}
@@ -1627,11 +1608,12 @@ GNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio,
1627 GNUNET_SCHEDULER_TaskIdentifier 1608 GNUNET_SCHEDULER_TaskIdentifier
1628 prerequisite_task, 1609 prerequisite_task,
1629 struct GNUNET_TIME_Relative delay, 1610 struct GNUNET_TIME_Relative delay,
1630 const struct GNUNET_NETWORK_FDSet * rs, 1611 const struct GNUNET_NETWORK_FDSet *rs,
1631 const struct GNUNET_NETWORK_FDSet * ws, 1612 const struct GNUNET_NETWORK_FDSet *ws,
1632 GNUNET_SCHEDULER_Task task, void *task_cls) 1613 GNUNET_SCHEDULER_Task task, void *task_cls)
1633{ 1614{
1634 struct Task *t; 1615 struct Task *t;
1616
1635#if EXECINFO 1617#if EXECINFO
1636 void *backtrace_array[MAX_TRACE_DEPTH]; 1618 void *backtrace_array[MAX_TRACE_DEPTH];
1637#endif 1619#endif
@@ -1642,21 +1624,22 @@ GNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio,
1642 t->callback = task; 1624 t->callback = task;
1643 t->callback_cls = task_cls; 1625 t->callback_cls = task_cls;
1644#if EXECINFO 1626#if EXECINFO
1645 t->num_backtrace_strings = backtrace(backtrace_array, MAX_TRACE_DEPTH); 1627 t->num_backtrace_strings = backtrace (backtrace_array, MAX_TRACE_DEPTH);
1646 t->backtrace_strings = backtrace_symbols(backtrace_array, t->num_backtrace_strings); 1628 t->backtrace_strings =
1629 backtrace_symbols (backtrace_array, t->num_backtrace_strings);
1647#endif 1630#endif
1648 t->read_fd = -1; 1631 t->read_fd = -1;
1649 t->write_fd = -1; 1632 t->write_fd = -1;
1650 if (rs != NULL) 1633 if (rs != NULL)
1651 { 1634 {
1652 t->read_set = GNUNET_NETWORK_fdset_create (); 1635 t->read_set = GNUNET_NETWORK_fdset_create ();
1653 GNUNET_NETWORK_fdset_copy (t->read_set, rs); 1636 GNUNET_NETWORK_fdset_copy (t->read_set, rs);
1654 } 1637 }
1655 if (ws != NULL) 1638 if (ws != NULL)
1656 { 1639 {
1657 t->write_set = GNUNET_NETWORK_fdset_create (); 1640 t->write_set = GNUNET_NETWORK_fdset_create ();
1658 GNUNET_NETWORK_fdset_copy (t->write_set, ws); 1641 GNUNET_NETWORK_fdset_copy (t->write_set, ws);
1659 } 1642 }
1660 t->id = ++last_id; 1643 t->id = ++last_id;
1661#if PROFILE_DELAYS 1644#if PROFILE_DELAYS
1662 t->start_time = GNUNET_TIME_absolute_get (); 1645 t->start_time = GNUNET_TIME_absolute_get ();
@@ -1664,14 +1647,13 @@ GNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio,
1664 t->prereq_id = prerequisite_task; 1647 t->prereq_id = prerequisite_task;
1665 t->timeout = GNUNET_TIME_relative_to_absolute (delay); 1648 t->timeout = GNUNET_TIME_relative_to_absolute (delay);
1666 t->priority = 1649 t->priority =
1667 check_priority ((prio == 1650 check_priority ((prio ==
1668 GNUNET_SCHEDULER_PRIORITY_KEEP) ? current_priority 1651 GNUNET_SCHEDULER_PRIORITY_KEEP) ? current_priority
1669 : prio); 1652 : prio);
1670 t->lifeness = current_lifeness; 1653 t->lifeness = current_lifeness;
1671 t->next = pending; 1654 t->next = pending;
1672 pending = t; 1655 pending = t;
1673 max_priority_added = GNUNET_MAX (max_priority_added, 1656 max_priority_added = GNUNET_MAX (max_priority_added, t->priority);
1674 t->priority);
1675#if DEBUG_TASKS 1657#if DEBUG_TASKS
1676 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1658 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1677 "Adding task: %llu / %p\n", t->id, t->callback_cls); 1659 "Adding task: %llu / %p\n", t->id, t->callback_cls);
@@ -1679,12 +1661,9 @@ GNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio,
1679#if EXECINFO 1661#if EXECINFO
1680 int i; 1662 int i;
1681 1663
1682 for (i=0;i<t->num_backtrace_strings;i++) 1664 for (i = 0; i < t->num_backtrace_strings; i++)
1683 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1665 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1684 "Task %llu trace %d: %s\n", 1666 "Task %llu trace %d: %s\n", t->id, i, t->backtrace_strings[i]);
1685 t->id,
1686 i,
1687 t->backtrace_strings[i]);
1688#endif 1667#endif
1689 return t->id; 1668 return t->id;
1690} 1669}