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.c825
1 files changed, 407 insertions, 418 deletions
diff --git a/src/util/scheduler.c b/src/util/scheduler.c
index 7c5077fab..0c4374471 100644
--- a/src/util/scheduler.c
+++ b/src/util/scheduler.c
@@ -269,7 +269,7 @@ static void *scheduler_select_cls;
269 */ 269 */
270void 270void
271GNUNET_SCHEDULER_set_select (GNUNET_SCHEDULER_select new_select, 271GNUNET_SCHEDULER_set_select (GNUNET_SCHEDULER_select new_select,
272 void *new_select_cls) 272 void *new_select_cls)
273{ 273{
274 scheduler_select = new_select; 274 scheduler_select = new_select;
275 scheduler_select_cls = new_select_cls; 275 scheduler_select_cls = new_select_cls;
@@ -288,7 +288,7 @@ check_priority (enum GNUNET_SCHEDULER_Priority p)
288 if ((p >= 0) && (p < GNUNET_SCHEDULER_PRIORITY_COUNT)) 288 if ((p >= 0) && (p < GNUNET_SCHEDULER_PRIORITY_COUNT))
289 return p; 289 return p;
290 GNUNET_assert (0); 290 GNUNET_assert (0);
291 return 0; /* make compiler happy */ 291 return 0; /* make compiler happy */
292} 292}
293 293
294 294
@@ -310,37 +310,37 @@ is_pending (GNUNET_SCHEDULER_TaskIdentifier id)
310 310
311 if (id < lowest_pending_id) 311 if (id < lowest_pending_id)
312 return GNUNET_NO; 312 return GNUNET_NO;
313 min = -1; /* maximum value */ 313 min = -1; /* maximum value */
314 pos = pending; 314 pos = pending;
315 while (pos != NULL) 315 while (pos != NULL)
316 { 316 {
317 if (pos->id == id) 317 if (pos->id == id)
318 return GNUNET_YES; 318 return GNUNET_YES;
319 if (pos->id < min) 319 if (pos->id < min)
320 min = pos->id; 320 min = pos->id;
321 pos = pos->next; 321 pos = pos->next;
322 } 322 }
323 pos = pending_timeout; 323 pos = pending_timeout;
324 while (pos != NULL) 324 while (pos != NULL)
325 {
326 if (pos->id == id)
327 return GNUNET_YES;
328 if (pos->id < min)
329 min = pos->id;
330 pos = pos->next;
331 }
332 for (p = 0; p < GNUNET_SCHEDULER_PRIORITY_COUNT; p++)
333 {
334 pos = ready[p];
335 while (pos != NULL)
325 { 336 {
326 if (pos->id == id) 337 if (pos->id == id)
327 return GNUNET_YES; 338 return GNUNET_YES;
328 if (pos->id < min) 339 if (pos->id < min)
329 min = pos->id; 340 min = pos->id;
330 pos = pos->next; 341 pos = pos->next;
331 } 342 }
332 for (p = 0; p < GNUNET_SCHEDULER_PRIORITY_COUNT; p++) 343 }
333 {
334 pos = ready[p];
335 while (pos != NULL)
336 {
337 if (pos->id == id)
338 return GNUNET_YES;
339 if (pos->id < min)
340 min = pos->id;
341 pos = pos->next;
342 }
343 }
344 lowest_pending_id = min; 344 lowest_pending_id = min;
345 return GNUNET_NO; 345 return GNUNET_NO;
346} 346}
@@ -355,7 +355,7 @@ is_pending (GNUNET_SCHEDULER_TaskIdentifier id)
355 */ 355 */
356static void 356static void
357update_sets (struct GNUNET_NETWORK_FDSet *rs, struct GNUNET_NETWORK_FDSet *ws, 357update_sets (struct GNUNET_NETWORK_FDSet *rs, struct GNUNET_NETWORK_FDSet *ws,
358 struct GNUNET_TIME_Relative *timeout) 358 struct GNUNET_TIME_Relative *timeout)
359{ 359{
360 struct Task *pos; 360 struct Task *pos;
361 struct GNUNET_TIME_Absolute now; 361 struct GNUNET_TIME_Absolute now;
@@ -364,40 +364,40 @@ update_sets (struct GNUNET_NETWORK_FDSet *rs, struct GNUNET_NETWORK_FDSet *ws,
364 now = GNUNET_TIME_absolute_get (); 364 now = GNUNET_TIME_absolute_get ();
365 pos = pending_timeout; 365 pos = pending_timeout;
366 if (pos != NULL) 366 if (pos != NULL)
367 { 367 {
368 to = GNUNET_TIME_absolute_get_difference (now, pos->timeout); 368 to = GNUNET_TIME_absolute_get_difference (now, pos->timeout);
369 if (timeout->rel_value > to.rel_value) 369 if (timeout->rel_value > to.rel_value)
370 *timeout = to; 370 *timeout = to;
371 if (pos->reason != 0) 371 if (pos->reason != 0)
372 *timeout = GNUNET_TIME_UNIT_ZERO; 372 *timeout = GNUNET_TIME_UNIT_ZERO;
373 } 373 }
374 pos = pending; 374 pos = pending;
375 while (pos != NULL) 375 while (pos != NULL)
376 {
377 if ((pos->prereq_id != GNUNET_SCHEDULER_NO_TASK) &&
378 (GNUNET_YES == is_pending (pos->prereq_id)))
376 { 379 {
377 if ((pos->prereq_id != GNUNET_SCHEDULER_NO_TASK) &&
378 (GNUNET_YES == is_pending (pos->prereq_id)))
379 {
380 pos = pos->next;
381 continue;
382 }
383 if (pos->timeout.abs_value != GNUNET_TIME_UNIT_FOREVER_ABS.abs_value)
384 {
385 to = GNUNET_TIME_absolute_get_difference (now, pos->timeout);
386 if (timeout->rel_value > to.rel_value)
387 *timeout = to;
388 }
389 if (pos->read_fd != -1)
390 GNUNET_NETWORK_fdset_set_native (rs, pos->read_fd);
391 if (pos->write_fd != -1)
392 GNUNET_NETWORK_fdset_set_native (ws, pos->write_fd);
393 if (pos->read_set != NULL)
394 GNUNET_NETWORK_fdset_add (rs, pos->read_set);
395 if (pos->write_set != NULL)
396 GNUNET_NETWORK_fdset_add (ws, pos->write_set);
397 if (pos->reason != 0)
398 *timeout = GNUNET_TIME_UNIT_ZERO;
399 pos = pos->next; 380 pos = pos->next;
381 continue;
382 }
383 if (pos->timeout.abs_value != GNUNET_TIME_UNIT_FOREVER_ABS.abs_value)
384 {
385 to = GNUNET_TIME_absolute_get_difference (now, pos->timeout);
386 if (timeout->rel_value > to.rel_value)
387 *timeout = to;
400 } 388 }
389 if (pos->read_fd != -1)
390 GNUNET_NETWORK_fdset_set_native (rs, pos->read_fd);
391 if (pos->write_fd != -1)
392 GNUNET_NETWORK_fdset_set_native (ws, pos->write_fd);
393 if (pos->read_set != NULL)
394 GNUNET_NETWORK_fdset_add (rs, pos->read_set);
395 if (pos->write_set != NULL)
396 GNUNET_NETWORK_fdset_add (ws, pos->write_set);
397 if (pos->reason != 0)
398 *timeout = GNUNET_TIME_UNIT_ZERO;
399 pos = pos->next;
400 }
401} 401}
402 402
403 403
@@ -412,17 +412,17 @@ update_sets (struct GNUNET_NETWORK_FDSet *rs, struct GNUNET_NETWORK_FDSet *ws,
412 */ 412 */
413static int 413static int
414set_overlaps (const struct GNUNET_NETWORK_FDSet *ready, 414set_overlaps (const struct GNUNET_NETWORK_FDSet *ready,
415 struct GNUNET_NETWORK_FDSet *want) 415 struct GNUNET_NETWORK_FDSet *want)
416{ 416{
417 if ((NULL == want) || (NULL == ready)) 417 if ((NULL == want) || (NULL == ready))
418 return GNUNET_NO; 418 return GNUNET_NO;
419 if (GNUNET_NETWORK_fdset_overlap (ready, want)) 419 if (GNUNET_NETWORK_fdset_overlap (ready, want))
420 { 420 {
421 /* copy all over (yes, there maybe unrelated bits, 421 /* copy all over (yes, there maybe unrelated bits,
422 * but this should not hurt well-written clients) */ 422 * but this should not hurt well-written clients) */
423 GNUNET_NETWORK_fdset_copy (want, ready); 423 GNUNET_NETWORK_fdset_copy (want, ready);
424 return GNUNET_YES; 424 return GNUNET_YES;
425 } 425 }
426 return GNUNET_NO; 426 return GNUNET_NO;
427} 427}
428 428
@@ -439,8 +439,8 @@ set_overlaps (const struct GNUNET_NETWORK_FDSet *ready,
439 */ 439 */
440static int 440static int
441is_ready (struct Task *task, struct GNUNET_TIME_Absolute now, 441is_ready (struct Task *task, struct GNUNET_TIME_Absolute now,
442 const struct GNUNET_NETWORK_FDSet *rs, 442 const struct GNUNET_NETWORK_FDSet *rs,
443 const struct GNUNET_NETWORK_FDSet *ws) 443 const struct GNUNET_NETWORK_FDSet *ws)
444{ 444{
445 enum GNUNET_SCHEDULER_Reason reason; 445 enum GNUNET_SCHEDULER_Reason reason;
446 446
@@ -449,25 +449,25 @@ is_ready (struct Task *task, struct GNUNET_TIME_Absolute now,
449 reason |= GNUNET_SCHEDULER_REASON_TIMEOUT; 449 reason |= GNUNET_SCHEDULER_REASON_TIMEOUT;
450 if ((0 == (reason & GNUNET_SCHEDULER_REASON_READ_READY)) && 450 if ((0 == (reason & GNUNET_SCHEDULER_REASON_READ_READY)) &&
451 (((task->read_fd != -1) && 451 (((task->read_fd != -1) &&
452 (GNUNET_YES == GNUNET_NETWORK_fdset_test_native (rs, task->read_fd))) 452 (GNUNET_YES == GNUNET_NETWORK_fdset_test_native (rs, task->read_fd))) ||
453 || (set_overlaps (rs, task->read_set)))) 453 (set_overlaps (rs, task->read_set))))
454 reason |= GNUNET_SCHEDULER_REASON_READ_READY; 454 reason |= GNUNET_SCHEDULER_REASON_READ_READY;
455 if ((0 == (reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) && 455 if ((0 == (reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) &&
456 (((task->write_fd != -1) && 456 (((task->write_fd != -1) &&
457 (GNUNET_YES == GNUNET_NETWORK_fdset_test_native (ws, task->write_fd))) 457 (GNUNET_YES == GNUNET_NETWORK_fdset_test_native (ws, task->write_fd)))
458 || (set_overlaps (ws, task->write_set)))) 458 || (set_overlaps (ws, task->write_set))))
459 reason |= GNUNET_SCHEDULER_REASON_WRITE_READY; 459 reason |= GNUNET_SCHEDULER_REASON_WRITE_READY;
460 if (reason == 0) 460 if (reason == 0)
461 return GNUNET_NO; /* not ready */ 461 return GNUNET_NO; /* not ready */
462 if (task->prereq_id != GNUNET_SCHEDULER_NO_TASK) 462 if (task->prereq_id != GNUNET_SCHEDULER_NO_TASK)
463 {
464 if (GNUNET_YES == is_pending (task->prereq_id))
463 { 465 {
464 if (GNUNET_YES == is_pending (task->prereq_id)) 466 task->reason = reason;
465 { 467 return GNUNET_NO; /* prereq waiting */
466 task->reason = reason;
467 return GNUNET_NO; /* prereq waiting */
468 }
469 reason |= GNUNET_SCHEDULER_REASON_PREREQ_DONE;
470 } 468 }
469 reason |= GNUNET_SCHEDULER_REASON_PREREQ_DONE;
470 }
471 task->reason = reason; 471 task->reason = reason;
472 return GNUNET_YES; 472 return GNUNET_YES;
473} 473}
@@ -500,7 +500,7 @@ queue_ready_task (struct Task *task)
500 */ 500 */
501static void 501static void
502check_ready (const struct GNUNET_NETWORK_FDSet *rs, 502check_ready (const struct GNUNET_NETWORK_FDSet *rs,
503 const struct GNUNET_NETWORK_FDSet *ws) 503 const struct GNUNET_NETWORK_FDSet *ws)
504{ 504{
505 struct Task *pos; 505 struct Task *pos;
506 struct Task *prev; 506 struct Task *prev;
@@ -511,40 +511,39 @@ check_ready (const struct GNUNET_NETWORK_FDSet *rs,
511 prev = NULL; 511 prev = NULL;
512 pos = pending_timeout; 512 pos = pending_timeout;
513 while (pos != NULL) 513 while (pos != NULL)
514 { 514 {
515 next = pos->next; 515 next = pos->next;
516 if (now.abs_value >= pos->timeout.abs_value) 516 if (now.abs_value >= pos->timeout.abs_value)
517 pos->reason |= GNUNET_SCHEDULER_REASON_TIMEOUT; 517 pos->reason |= GNUNET_SCHEDULER_REASON_TIMEOUT;
518 if (0 == pos->reason) 518 if (0 == pos->reason)
519 break; 519 break;
520 pending_timeout = next; 520 pending_timeout = next;
521 if (pending_timeout_last == pos) 521 if (pending_timeout_last == pos)
522 pending_timeout_last = NULL; 522 pending_timeout_last = NULL;
523 queue_ready_task (pos); 523 queue_ready_task (pos);
524 pos = next; 524 pos = next;
525 } 525 }
526 pos = pending; 526 pos = pending;
527 while (pos != NULL) 527 while (pos != NULL)
528 { 528 {
529#if DEBUG_TASKS 529#if DEBUG_TASKS
530 LOG (GNUNET_ERROR_TYPE_DEBUG, 530 LOG (GNUNET_ERROR_TYPE_DEBUG, "Checking readiness of task: %llu / %p\n",
531 "Checking readiness of task: %llu / %p\n", pos->id, 531 pos->id, pos->callback_cls);
532 pos->callback_cls);
533#endif 532#endif
534 next = pos->next; 533 next = pos->next;
535 if (GNUNET_YES == is_ready (pos, now, rs, ws)) 534 if (GNUNET_YES == is_ready (pos, now, rs, ws))
536 { 535 {
537 if (prev == NULL) 536 if (prev == NULL)
538 pending = next; 537 pending = next;
539 else 538 else
540 prev->next = next; 539 prev->next = next;
541 queue_ready_task (pos); 540 queue_ready_task (pos);
542 pos = next;
543 continue;
544 }
545 prev = pos;
546 pos = next; 541 pos = next;
542 continue;
547 } 543 }
544 prev = pos;
545 pos = next;
546 }
548} 547}
549 548
550 549
@@ -563,15 +562,26 @@ GNUNET_SCHEDULER_shutdown ()
563 562
564 pos = pending_timeout; 563 pos = pending_timeout;
565 while (pos != NULL) 564 while (pos != NULL)
566 { 565 {
567 pos->reason |= GNUNET_SCHEDULER_REASON_SHUTDOWN; 566 pos->reason |= GNUNET_SCHEDULER_REASON_SHUTDOWN;
568 /* we don't move the task into the ready queue yet; check_ready 567 /* we don't move the task into the ready queue yet; check_ready
569 * will do that later, possibly adding additional 568 * will do that later, possibly adding additional
570 * readiness-factors */ 569 * readiness-factors */
571 pos = pos->next; 570 pos = pos->next;
572 } 571 }
573 pos = pending; 572 pos = pending;
574 while (pos != NULL) 573 while (pos != NULL)
574 {
575 pos->reason |= GNUNET_SCHEDULER_REASON_SHUTDOWN;
576 /* we don't move the task into the ready queue yet; check_ready
577 * will do that later, possibly adding additional
578 * readiness-factors */
579 pos = pos->next;
580 }
581 for (i = 0; i < GNUNET_SCHEDULER_PRIORITY_COUNT; i++)
582 {
583 pos = ready[i];
584 while (pos != NULL)
575 { 585 {
576 pos->reason |= GNUNET_SCHEDULER_REASON_SHUTDOWN; 586 pos->reason |= GNUNET_SCHEDULER_REASON_SHUTDOWN;
577 /* we don't move the task into the ready queue yet; check_ready 587 /* we don't move the task into the ready queue yet; check_ready
@@ -579,18 +589,7 @@ GNUNET_SCHEDULER_shutdown ()
579 * readiness-factors */ 589 * readiness-factors */
580 pos = pos->next; 590 pos = pos->next;
581 } 591 }
582 for (i = 0; i < GNUNET_SCHEDULER_PRIORITY_COUNT; i++) 592 }
583 {
584 pos = ready[i];
585 while (pos != NULL)
586 {
587 pos->reason |= GNUNET_SCHEDULER_REASON_SHUTDOWN;
588 /* we don't move the task into the ready queue yet; check_ready
589 * will do that later, possibly adding additional
590 * readiness-factors */
591 pos = pos->next;
592 }
593 }
594} 593}
595 594
596 595
@@ -632,69 +631,68 @@ run_ready (struct GNUNET_NETWORK_FDSet *rs, struct GNUNET_NETWORK_FDSet *ws)
632 631
633 max_priority_added = GNUNET_SCHEDULER_PRIORITY_KEEP; 632 max_priority_added = GNUNET_SCHEDULER_PRIORITY_KEEP;
634 do 633 do
634 {
635 if (ready_count == 0)
636 return;
637 GNUNET_assert (ready[GNUNET_SCHEDULER_PRIORITY_KEEP] == NULL);
638 /* yes, p>0 is correct, 0 is "KEEP" which should
639 * always be an empty queue (see assertion)! */
640 for (p = GNUNET_SCHEDULER_PRIORITY_COUNT - 1; p > 0; p--)
635 { 641 {
636 if (ready_count == 0) 642 pos = ready[p];
637 return; 643 if (pos != NULL)
638 GNUNET_assert (ready[GNUNET_SCHEDULER_PRIORITY_KEEP] == NULL); 644 break;
639 /* yes, p>0 is correct, 0 is "KEEP" which should 645 }
640 * always be an empty queue (see assertion)! */ 646 GNUNET_assert (pos != NULL); /* ready_count wrong? */
641 for (p = GNUNET_SCHEDULER_PRIORITY_COUNT - 1; p > 0; p--) 647 ready[p] = pos->next;
642 { 648 ready_count--;
643 pos = ready[p]; 649 if (current_priority != pos->priority)
644 if (pos != NULL) 650 {
645 break; 651 current_priority = pos->priority;
646 } 652 (void) GNUNET_OS_set_process_priority (GNUNET_OS_process_current (),
647 GNUNET_assert (pos != NULL); /* ready_count wrong? */ 653 pos->priority);
648 ready[p] = pos->next; 654 }
649 ready_count--; 655 current_lifeness = pos->lifeness;
650 if (current_priority != pos->priority) 656 active_task = pos;
651 {
652 current_priority = pos->priority;
653 (void) GNUNET_OS_set_process_priority (GNUNET_OS_process_current (),
654 pos->priority);
655 }
656 current_lifeness = pos->lifeness;
657 active_task = pos;
658#if PROFILE_DELAYS 657#if PROFILE_DELAYS
659 if (GNUNET_TIME_absolute_get_duration (pos->start_time).rel_value > 658 if (GNUNET_TIME_absolute_get_duration (pos->start_time).rel_value >
660 DELAY_THRESHOLD.rel_value) 659 DELAY_THRESHOLD.rel_value)
661 { 660 {
662 LOG (GNUNET_ERROR_TYPE_ERROR, 661 LOG (GNUNET_ERROR_TYPE_ERROR, "Task %llu took %llums to be scheduled\n",
663 "Task %llu took %llums to be scheduled\n", pos->id, 662 pos->id,
664 (unsigned long long) 663 (unsigned long long)
665 GNUNET_TIME_absolute_get_duration (pos->start_time).rel_value); 664 GNUNET_TIME_absolute_get_duration (pos->start_time).rel_value);
666 } 665 }
667#endif 666#endif
668 tc.reason = pos->reason; 667 tc.reason = pos->reason;
669 tc.read_ready = (pos->read_set == NULL) ? rs : pos->read_set; 668 tc.read_ready = (pos->read_set == NULL) ? rs : pos->read_set;
670 if ((pos->read_fd != -1) && 669 if ((pos->read_fd != -1) &&
671 (0 != (pos->reason & GNUNET_SCHEDULER_REASON_READ_READY))) 670 (0 != (pos->reason & GNUNET_SCHEDULER_REASON_READ_READY)))
672 GNUNET_NETWORK_fdset_set_native (rs, pos->read_fd); 671 GNUNET_NETWORK_fdset_set_native (rs, pos->read_fd);
673 tc.write_ready = (pos->write_set == NULL) ? ws : pos->write_set; 672 tc.write_ready = (pos->write_set == NULL) ? ws : pos->write_set;
674 if ((pos->write_fd != -1) && 673 if ((pos->write_fd != -1) &&
675 (0 != (pos->reason & GNUNET_SCHEDULER_REASON_WRITE_READY))) 674 (0 != (pos->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)))
676 GNUNET_NETWORK_fdset_set_native (ws, pos->write_fd); 675 GNUNET_NETWORK_fdset_set_native (ws, pos->write_fd);
677 if (((tc.reason & GNUNET_SCHEDULER_REASON_WRITE_READY) != 0) && 676 if (((tc.reason & GNUNET_SCHEDULER_REASON_WRITE_READY) != 0) &&
678 (pos->write_fd != -1) && 677 (pos->write_fd != -1) &&
679 (!GNUNET_NETWORK_fdset_test_native (ws, pos->write_fd))) 678 (!GNUNET_NETWORK_fdset_test_native (ws, pos->write_fd)))
680 abort (); // added to ready in previous select loop! 679 abort (); // added to ready in previous select loop!
681#if DEBUG_TASKS 680#if DEBUG_TASKS
682 LOG (GNUNET_ERROR_TYPE_DEBUG, 681 LOG (GNUNET_ERROR_TYPE_DEBUG, "Running task: %llu / %p\n", pos->id,
683 "Running task: %llu / %p\n", pos->id, pos->callback_cls); 682 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 687
689 for (i = 0; i < pos->num_backtrace_strings; i++) 688 for (i = 0; i < pos->num_backtrace_strings; i++)
690 LOG (GNUNET_ERROR_TYPE_ERROR, 689 LOG (GNUNET_ERROR_TYPE_ERROR, "Task %llu trace %d: %s\n", pos->id, i,
691 "Task %llu trace %d: %s\n", pos->id, 690 pos->backtrace_strings[i]);
692 i, pos->backtrace_strings[i]);
693#endif 691#endif
694 active_task = NULL; 692 active_task = NULL;
695 destroy_task (pos); 693 destroy_task (pos);
696 tasks_run++; 694 tasks_run++;
697 } 695 }
698 while ((pending == NULL) || (p >= max_priority_added)); 696 while ((pending == NULL) || (p >= max_priority_added));
699} 697}
700 698
@@ -720,11 +718,11 @@ static void
720sighandler_shutdown () 718sighandler_shutdown ()
721{ 719{
722 static char c; 720 static char c;
723 int old_errno = errno; /* backup errno */ 721 int old_errno = errno; /* backup errno */
724 722
725 GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle 723 GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle
726 (shutdown_pipe_handle, GNUNET_DISK_PIPE_END_WRITE), 724 (shutdown_pipe_handle, GNUNET_DISK_PIPE_END_WRITE),
727 &c, sizeof (c)); 725 &c, sizeof (c));
728 errno = old_errno; 726 errno = old_errno;
729} 727}
730 728
@@ -750,10 +748,10 @@ check_lifeness ()
750 if (t->lifeness == GNUNET_YES) 748 if (t->lifeness == GNUNET_YES)
751 return GNUNET_OK; 749 return GNUNET_OK;
752 if ((NULL != pending) || (NULL != pending_timeout)) 750 if ((NULL != pending) || (NULL != pending_timeout))
753 { 751 {
754 GNUNET_SCHEDULER_shutdown (); 752 GNUNET_SCHEDULER_shutdown ();
755 return GNUNET_OK; 753 return GNUNET_OK;
756 } 754 }
757 return GNUNET_NO; 755 return GNUNET_NO;
758} 756}
759 757
@@ -799,7 +797,7 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_Task task, void *task_cls)
799 shutdown_pipe_handle = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO); 797 shutdown_pipe_handle = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO);
800 GNUNET_assert (shutdown_pipe_handle != NULL); 798 GNUNET_assert (shutdown_pipe_handle != NULL);
801 pr = GNUNET_DISK_pipe_handle (shutdown_pipe_handle, 799 pr = GNUNET_DISK_pipe_handle (shutdown_pipe_handle,
802 GNUNET_DISK_PIPE_END_READ); 800 GNUNET_DISK_PIPE_END_READ);
803 GNUNET_assert (pr != NULL); 801 GNUNET_assert (pr != NULL);
804 shc_int = GNUNET_SIGNAL_handler_install (SIGINT, &sighandler_shutdown); 802 shc_int = GNUNET_SIGNAL_handler_install (SIGINT, &sighandler_shutdown);
805 shc_term = GNUNET_SIGNAL_handler_install (SIGTERM, &sighandler_shutdown); 803 shc_term = GNUNET_SIGNAL_handler_install (SIGTERM, &sighandler_shutdown);
@@ -811,77 +809,76 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_Task task, void *task_cls)
811 current_priority = GNUNET_SCHEDULER_PRIORITY_DEFAULT; 809 current_priority = GNUNET_SCHEDULER_PRIORITY_DEFAULT;
812 current_lifeness = GNUNET_YES; 810 current_lifeness = GNUNET_YES;
813 GNUNET_SCHEDULER_add_continuation (task, task_cls, 811 GNUNET_SCHEDULER_add_continuation (task, task_cls,
814 GNUNET_SCHEDULER_REASON_STARTUP); 812 GNUNET_SCHEDULER_REASON_STARTUP);
815#if ENABLE_WINDOWS_WORKAROUNDS 813#if ENABLE_WINDOWS_WORKAROUNDS
816 active_task = (void *) (long) -1; /* force passing of sanity check */ 814 active_task = (void *) (long) -1; /* force passing of sanity check */
817 GNUNET_SCHEDULER_add_now_with_lifeness (GNUNET_NO, 815 GNUNET_SCHEDULER_add_now_with_lifeness (GNUNET_NO,
818 &GNUNET_OS_install_parent_control_handler, 816 &GNUNET_OS_install_parent_control_handler,
819 NULL); 817 NULL);
820 active_task = NULL; 818 active_task = NULL;
821#endif 819#endif
822 last_tr = 0; 820 last_tr = 0;
823 busy_wait_warning = 0; 821 busy_wait_warning = 0;
824 while (GNUNET_OK == check_lifeness ()) 822 while (GNUNET_OK == check_lifeness ())
823 {
824 GNUNET_NETWORK_fdset_zero (rs);
825 GNUNET_NETWORK_fdset_zero (ws);
826 timeout = GNUNET_TIME_UNIT_FOREVER_REL;
827 update_sets (rs, ws, &timeout);
828 GNUNET_NETWORK_fdset_handle_set (rs, pr);
829 if (ready_count > 0)
825 { 830 {
826 GNUNET_NETWORK_fdset_zero (rs); 831 /* no blocking, more work already ready! */
827 GNUNET_NETWORK_fdset_zero (ws); 832 timeout = GNUNET_TIME_UNIT_ZERO;
828 timeout = GNUNET_TIME_UNIT_FOREVER_REL; 833 }
829 update_sets (rs, ws, &timeout); 834 if (NULL == scheduler_select)
830 GNUNET_NETWORK_fdset_handle_set (rs, pr); 835 ret = GNUNET_NETWORK_socket_select (rs, ws, NULL, timeout);
831 if (ready_count > 0) 836 else
832 { 837 ret = scheduler_select (scheduler_select_cls, rs, ws, NULL, timeout);
833 /* no blocking, more work already ready! */ 838 if (ret == GNUNET_SYSERR)
834 timeout = GNUNET_TIME_UNIT_ZERO; 839 {
835 } 840 if (errno == EINTR)
836 if (NULL == scheduler_select) 841 continue;
837 ret = GNUNET_NETWORK_socket_select (rs, ws, NULL, timeout);
838 else
839 ret = scheduler_select (scheduler_select_cls, rs, ws, NULL, timeout);
840 if (ret == GNUNET_SYSERR)
841 {
842 if (errno == EINTR)
843 continue;
844 842
845 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "select"); 843 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "select");
846#ifndef MINGW 844#ifndef MINGW
847#if USE_LSOF 845#if USE_LSOF
848 char lsof[512]; 846 char lsof[512];
849 847
850 snprintf (lsof, sizeof (lsof), "lsof -p %d", getpid ()); 848 snprintf (lsof, sizeof (lsof), "lsof -p %d", getpid ());
851 (void) close (1); 849 (void) close (1);
852 (void) dup2 (2, 1); 850 (void) dup2 (2, 1);
853 if (0 != system (lsof)) 851 if (0 != system (lsof))
854 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "system"); 852 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "system");
855#endif 853#endif
856#endif 854#endif
857 abort (); 855 abort ();
858 break; 856 break;
859 } 857 }
860 if ((ret == 0) && (timeout.rel_value == 0) && (busy_wait_warning > 16)) 858 if ((ret == 0) && (timeout.rel_value == 0) && (busy_wait_warning > 16))
861 { 859 {
862 LOG (GNUNET_ERROR_TYPE_WARNING, 860 LOG (GNUNET_ERROR_TYPE_WARNING, _("Looks like we're busy waiting...\n"));
863 _("Looks like we're busy waiting...\n")); 861 sleep (1); /* mitigate */
864 sleep (1); /* mitigate */ 862 }
865 } 863 check_ready (rs, ws);
866 check_ready (rs, ws); 864 run_ready (rs, ws);
867 run_ready (rs, ws); 865 if (GNUNET_NETWORK_fdset_handle_isset (rs, pr))
868 if (GNUNET_NETWORK_fdset_handle_isset (rs, pr)) 866 {
869 { 867 /* consume the signal */
870 /* consume the signal */ 868 GNUNET_DISK_file_read (pr, &c, sizeof (c));
871 GNUNET_DISK_file_read (pr, &c, sizeof (c)); 869 /* mark all active tasks as ready due to shutdown */
872 /* mark all active tasks as ready due to shutdown */ 870 GNUNET_SCHEDULER_shutdown ();
873 GNUNET_SCHEDULER_shutdown (); 871 }
874 } 872 if (last_tr == tasks_run)
875 if (last_tr == tasks_run) 873 {
876 { 874 busy_wait_warning++;
877 busy_wait_warning++; 875 }
878 } 876 else
879 else 877 {
880 { 878 last_tr = tasks_run;
881 last_tr = tasks_run; 879 busy_wait_warning = 0;
882 busy_wait_warning = 0;
883 }
884 } 880 }
881 }
885 GNUNET_SIGNAL_handler_uninstall (shc_int); 882 GNUNET_SIGNAL_handler_uninstall (shc_int);
886 GNUNET_SIGNAL_handler_uninstall (shc_term); 883 GNUNET_SIGNAL_handler_uninstall (shc_term);
887#ifndef MINGW 884#ifndef MINGW
@@ -934,10 +931,10 @@ GNUNET_SCHEDULER_get_load (enum GNUNET_SCHEDULER_Priority p)
934 ret = 0; 931 ret = 0;
935 pos = ready[check_priority (p)]; 932 pos = ready[check_priority (p)];
936 while (pos != NULL) 933 while (pos != NULL)
937 { 934 {
938 pos = pos->next; 935 pos = pos->next;
939 ret++; 936 ret++;
940 } 937 }
941 return ret; 938 return ret;
942} 939}
943 940
@@ -963,77 +960,76 @@ GNUNET_SCHEDULER_cancel (GNUNET_SCHEDULER_TaskIdentifier task)
963 prev = NULL; 960 prev = NULL;
964 t = pending; 961 t = pending;
965 while (t != NULL) 962 while (t != NULL)
963 {
964 if (t->id == task)
965 break;
966 prev = t;
967 t = t->next;
968 }
969 if (t == NULL)
970 {
971 prev = NULL;
972 to = 1;
973 t = pending_timeout;
974 while (t != NULL)
966 { 975 {
967 if (t->id == task) 976 if (t->id == task)
968 break; 977 break;
969 prev = t; 978 prev = t;
970 t = t->next; 979 t = t->next;
971 } 980 }
972 if (t == NULL) 981 if (pending_timeout_last == t)
973 { 982 pending_timeout_last = NULL;
974 prev = NULL; 983 }
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; 984 p = 0;
988 while (t == NULL) 985 while (t == NULL)
986 {
987 p++;
988 if (p >= GNUNET_SCHEDULER_PRIORITY_COUNT)
989 { 989 {
990 p++; 990 LOG (GNUNET_ERROR_TYPE_ERROR, _("Attempt to cancel dead task %llu!\n"),
991 if (p >= GNUNET_SCHEDULER_PRIORITY_COUNT) 991 (unsigned long long) task);
992 { 992 GNUNET_assert (0);
993 LOG (GNUNET_ERROR_TYPE_ERROR,
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 } 993 }
994 prev = NULL;
995 t = ready[p];
996 while (t != NULL)
997 {
998 if (t->id == task)
999 {
1000 ready_count--;
1001 break;
1002 }
1003 prev = t;
1004 t = t->next;
1005 }
1006 }
1011 if (prev == NULL) 1007 if (prev == NULL)
1008 {
1009 if (p == 0)
1012 { 1010 {
1013 if (p == 0) 1011 if (to == 0)
1014 { 1012 {
1015 if (to == 0) 1013 pending = t->next;
1016 { 1014 }
1017 pending = t->next;
1018 }
1019 else
1020 {
1021 pending_timeout = t->next;
1022 }
1023 }
1024 else 1015 else
1025 { 1016 {
1026 ready[p] = t->next; 1017 pending_timeout = t->next;
1027 } 1018 }
1028 } 1019 }
1029 else 1020 else
1030 { 1021 {
1031 prev->next = t->next; 1022 ready[p] = t->next;
1032 } 1023 }
1024 }
1025 else
1026 {
1027 prev->next = t->next;
1028 }
1033 ret = t->callback_cls; 1029 ret = t->callback_cls;
1034#if DEBUG_TASKS 1030#if DEBUG_TASKS
1035 LOG (GNUNET_ERROR_TYPE_DEBUG, 1031 LOG (GNUNET_ERROR_TYPE_DEBUG, "Canceling task: %llu / %p\n", task,
1036 "Canceling task: %llu / %p\n", task, t->callback_cls); 1032 t->callback_cls);
1037#endif 1033#endif
1038 destroy_task (t); 1034 destroy_task (t);
1039 return ret; 1035 return ret;
@@ -1051,7 +1047,7 @@ GNUNET_SCHEDULER_cancel (GNUNET_SCHEDULER_TaskIdentifier task)
1051 */ 1047 */
1052void 1048void
1053GNUNET_SCHEDULER_add_continuation (GNUNET_SCHEDULER_Task task, void *task_cls, 1049GNUNET_SCHEDULER_add_continuation (GNUNET_SCHEDULER_Task task, void *task_cls,
1054 enum GNUNET_SCHEDULER_Reason reason) 1050 enum GNUNET_SCHEDULER_Reason reason)
1055{ 1051{
1056 struct Task *t; 1052 struct Task *t;
1057 1053
@@ -1061,12 +1057,12 @@ GNUNET_SCHEDULER_add_continuation (GNUNET_SCHEDULER_Task task, void *task_cls,
1061 1057
1062 GNUNET_assert (NULL != task); 1058 GNUNET_assert (NULL != task);
1063 GNUNET_assert ((active_task != NULL) || 1059 GNUNET_assert ((active_task != NULL) ||
1064 (reason == GNUNET_SCHEDULER_REASON_STARTUP)); 1060 (reason == GNUNET_SCHEDULER_REASON_STARTUP));
1065 t = GNUNET_malloc (sizeof (struct Task)); 1061 t = GNUNET_malloc (sizeof (struct Task));
1066#if EXECINFO 1062#if EXECINFO
1067 t->num_backtrace_strings = backtrace (backtrace_array, 50); 1063 t->num_backtrace_strings = backtrace (backtrace_array, 50);
1068 t->backtrace_strings = 1064 t->backtrace_strings =
1069 backtrace_symbols (backtrace_array, t->num_backtrace_strings); 1065 backtrace_symbols (backtrace_array, t->num_backtrace_strings);
1070#endif 1066#endif
1071 t->read_fd = -1; 1067 t->read_fd = -1;
1072 t->write_fd = -1; 1068 t->write_fd = -1;
@@ -1080,8 +1076,8 @@ GNUNET_SCHEDULER_add_continuation (GNUNET_SCHEDULER_Task task, void *task_cls,
1080 t->priority = current_priority; 1076 t->priority = current_priority;
1081 t->lifeness = current_lifeness; 1077 t->lifeness = current_lifeness;
1082#if DEBUG_TASKS 1078#if DEBUG_TASKS
1083 LOG (GNUNET_ERROR_TYPE_DEBUG, 1079 LOG (GNUNET_ERROR_TYPE_DEBUG, "Adding continuation task: %llu / %p\n", t->id,
1084 "Adding continuation task: %llu / %p\n", t->id, t->callback_cls); 1080 t->callback_cls);
1085#endif 1081#endif
1086 queue_ready_task (t); 1082 queue_ready_task (t);
1087} 1083}
@@ -1106,12 +1102,11 @@ GNUNET_SCHEDULER_add_continuation (GNUNET_SCHEDULER_Task task, void *task_cls,
1106 */ 1102 */
1107GNUNET_SCHEDULER_TaskIdentifier 1103GNUNET_SCHEDULER_TaskIdentifier
1108GNUNET_SCHEDULER_add_after (GNUNET_SCHEDULER_TaskIdentifier prerequisite_task, 1104GNUNET_SCHEDULER_add_after (GNUNET_SCHEDULER_TaskIdentifier prerequisite_task,
1109 GNUNET_SCHEDULER_Task task, void *task_cls) 1105 GNUNET_SCHEDULER_Task task, void *task_cls)
1110{ 1106{
1111 return GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_KEEP, 1107 return GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_KEEP,
1112 prerequisite_task, 1108 prerequisite_task, GNUNET_TIME_UNIT_ZERO,
1113 GNUNET_TIME_UNIT_ZERO, NULL, NULL, task, 1109 NULL, NULL, task, task_cls);
1114 task_cls);
1115} 1110}
1116 1111
1117 1112
@@ -1126,12 +1121,11 @@ GNUNET_SCHEDULER_add_after (GNUNET_SCHEDULER_TaskIdentifier prerequisite_task,
1126 */ 1121 */
1127GNUNET_SCHEDULER_TaskIdentifier 1122GNUNET_SCHEDULER_TaskIdentifier
1128GNUNET_SCHEDULER_add_with_priority (enum GNUNET_SCHEDULER_Priority prio, 1123GNUNET_SCHEDULER_add_with_priority (enum GNUNET_SCHEDULER_Priority prio,
1129 GNUNET_SCHEDULER_Task task, 1124 GNUNET_SCHEDULER_Task task, void *task_cls)
1130 void *task_cls)
1131{ 1125{
1132 return GNUNET_SCHEDULER_add_select (prio, GNUNET_SCHEDULER_NO_TASK, 1126 return GNUNET_SCHEDULER_add_select (prio, GNUNET_SCHEDULER_NO_TASK,
1133 GNUNET_TIME_UNIT_ZERO, NULL, NULL, task, 1127 GNUNET_TIME_UNIT_ZERO, NULL, NULL, task,
1134 task_cls); 1128 task_cls);
1135} 1129}
1136 1130
1137 1131
@@ -1150,7 +1144,7 @@ GNUNET_SCHEDULER_add_with_priority (enum GNUNET_SCHEDULER_Priority prio,
1150 */ 1144 */
1151GNUNET_SCHEDULER_TaskIdentifier 1145GNUNET_SCHEDULER_TaskIdentifier
1152GNUNET_SCHEDULER_add_delayed (struct GNUNET_TIME_Relative delay, 1146GNUNET_SCHEDULER_add_delayed (struct GNUNET_TIME_Relative delay,
1153 GNUNET_SCHEDULER_Task task, void *task_cls) 1147 GNUNET_SCHEDULER_Task task, void *task_cls)
1154{ 1148{
1155#if 1 1149#if 1
1156 /* new, optimized version */ 1150 /* new, optimized version */
@@ -1170,7 +1164,7 @@ GNUNET_SCHEDULER_add_delayed (struct GNUNET_TIME_Relative delay,
1170#if EXECINFO 1164#if EXECINFO
1171 t->num_backtrace_strings = backtrace (backtrace_array, MAX_TRACE_DEPTH); 1165 t->num_backtrace_strings = backtrace (backtrace_array, MAX_TRACE_DEPTH);
1172 t->backtrace_strings = 1166 t->backtrace_strings =
1173 backtrace_symbols (backtrace_array, t->num_backtrace_strings); 1167 backtrace_symbols (backtrace_array, t->num_backtrace_strings);
1174#endif 1168#endif
1175 t->read_fd = -1; 1169 t->read_fd = -1;
1176 t->write_fd = -1; 1170 t->write_fd = -1;
@@ -1185,24 +1179,24 @@ GNUNET_SCHEDULER_add_delayed (struct GNUNET_TIME_Relative delay,
1185 * appending to a long list of tasks with timeouts) */ 1179 * appending to a long list of tasks with timeouts) */
1186 prev = pending_timeout_last; 1180 prev = pending_timeout_last;
1187 if (prev != NULL) 1181 if (prev != NULL)
1188 { 1182 {
1189 if (prev->timeout.abs_value > t->timeout.abs_value) 1183 if (prev->timeout.abs_value > t->timeout.abs_value)
1190 prev = NULL; 1184 prev = NULL;
1191 else 1185 else
1192 pos = prev->next; /* heuristic success! */ 1186 pos = prev->next; /* heuristic success! */
1193 } 1187 }
1194 if (prev == NULL) 1188 if (prev == NULL)
1195 { 1189 {
1196 /* heuristic failed, do traversal of timeout list */ 1190 /* heuristic failed, do traversal of timeout list */
1197 pos = pending_timeout; 1191 pos = pending_timeout;
1198 } 1192 }
1199 while ((pos != NULL) && 1193 while ((pos != NULL) &&
1200 ((pos->timeout.abs_value <= t->timeout.abs_value) || 1194 ((pos->timeout.abs_value <= t->timeout.abs_value) ||
1201 (pos->reason != 0))) 1195 (pos->reason != 0)))
1202 { 1196 {
1203 prev = pos; 1197 prev = pos;
1204 pos = pos->next; 1198 pos = pos->next;
1205 } 1199 }
1206 if (prev == NULL) 1200 if (prev == NULL)
1207 pending_timeout = t; 1201 pending_timeout = t;
1208 else 1202 else
@@ -1212,23 +1206,23 @@ GNUNET_SCHEDULER_add_delayed (struct GNUNET_TIME_Relative delay,
1212 pending_timeout_last = t; 1206 pending_timeout_last = t;
1213 1207
1214#if DEBUG_TASKS 1208#if DEBUG_TASKS
1215 LOG (GNUNET_ERROR_TYPE_DEBUG, 1209 LOG (GNUNET_ERROR_TYPE_DEBUG, "Adding task: %llu / %p\n", t->id,
1216 "Adding task: %llu / %p\n", t->id, t->callback_cls); 1210 t->callback_cls);
1217#endif 1211#endif
1218#if EXECINFO 1212#if EXECINFO
1219 int i; 1213 int i;
1220 1214
1221 for (i = 0; i < t->num_backtrace_strings; i++) 1215 for (i = 0; i < t->num_backtrace_strings; i++)
1222 LOG (GNUNET_ERROR_TYPE_DEBUG, 1216 LOG (GNUNET_ERROR_TYPE_DEBUG, "Task %llu trace %d: %s\n", t->id, i,
1223 "Task %llu trace %d: %s\n", t->id, i, t->backtrace_strings[i]); 1217 t->backtrace_strings[i]);
1224#endif 1218#endif
1225 return t->id; 1219 return t->id;
1226 1220
1227#else 1221#else
1228 /* unoptimized version */ 1222 /* unoptimized version */
1229 return GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_KEEP, 1223 return GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_KEEP,
1230 GNUNET_SCHEDULER_NO_TASK, delay, NULL, 1224 GNUNET_SCHEDULER_NO_TASK, delay, NULL,
1231 NULL, task, task_cls); 1225 NULL, task, task_cls);
1232#endif 1226#endif
1233} 1227}
1234 1228
@@ -1247,9 +1241,9 @@ GNUNET_SCHEDULER_TaskIdentifier
1247GNUNET_SCHEDULER_add_now (GNUNET_SCHEDULER_Task task, void *task_cls) 1241GNUNET_SCHEDULER_add_now (GNUNET_SCHEDULER_Task task, void *task_cls)
1248{ 1242{
1249 return GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_KEEP, 1243 return GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_KEEP,
1250 GNUNET_SCHEDULER_NO_TASK, 1244 GNUNET_SCHEDULER_NO_TASK,
1251 GNUNET_TIME_UNIT_ZERO, NULL, NULL, task, 1245 GNUNET_TIME_UNIT_ZERO, NULL, NULL, task,
1252 task_cls); 1246 task_cls);
1253} 1247}
1254 1248
1255 1249
@@ -1269,16 +1263,16 @@ GNUNET_SCHEDULER_add_now (GNUNET_SCHEDULER_Task task, void *task_cls)
1269 */ 1263 */
1270GNUNET_SCHEDULER_TaskIdentifier 1264GNUNET_SCHEDULER_TaskIdentifier
1271GNUNET_SCHEDULER_add_now_with_lifeness (int lifeness, 1265GNUNET_SCHEDULER_add_now_with_lifeness (int lifeness,
1272 GNUNET_SCHEDULER_Task task, 1266 GNUNET_SCHEDULER_Task task,
1273 void *task_cls) 1267 void *task_cls)
1274{ 1268{
1275 GNUNET_SCHEDULER_TaskIdentifier ret; 1269 GNUNET_SCHEDULER_TaskIdentifier ret;
1276 1270
1277 ret = 1271 ret =
1278 GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_KEEP, 1272 GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_KEEP,
1279 GNUNET_SCHEDULER_NO_TASK, 1273 GNUNET_SCHEDULER_NO_TASK,
1280 GNUNET_TIME_UNIT_ZERO, NULL, NULL, task, 1274 GNUNET_TIME_UNIT_ZERO, NULL, NULL, task,
1281 task_cls); 1275 task_cls);
1282 GNUNET_assert (pending->id == ret); 1276 GNUNET_assert (pending->id == ret);
1283 pending->lifeness = lifeness; 1277 pending->lifeness = lifeness;
1284 return ret; 1278 return ret;
@@ -1316,7 +1310,7 @@ GNUNET_SCHEDULER_add_now_with_lifeness (int lifeness,
1316#ifndef MINGW 1310#ifndef MINGW
1317GNUNET_SCHEDULER_TaskIdentifier 1311GNUNET_SCHEDULER_TaskIdentifier
1318add_without_sets (struct GNUNET_TIME_Relative delay, int rfd, int wfd, 1312add_without_sets (struct GNUNET_TIME_Relative delay, int rfd, int wfd,
1319 GNUNET_SCHEDULER_Task task, void *task_cls) 1313 GNUNET_SCHEDULER_Task task, void *task_cls)
1320{ 1314{
1321 struct Task *t; 1315 struct Task *t;
1322 1316
@@ -1332,45 +1326,41 @@ add_without_sets (struct GNUNET_TIME_Relative delay, int rfd, int wfd,
1332#if EXECINFO 1326#if EXECINFO
1333 t->num_backtrace_strings = backtrace (backtrace_array, MAX_TRACE_DEPTH); 1327 t->num_backtrace_strings = backtrace (backtrace_array, MAX_TRACE_DEPTH);
1334 t->backtrace_strings = 1328 t->backtrace_strings =
1335 backtrace_symbols (backtrace_array, t->num_backtrace_strings); 1329 backtrace_symbols (backtrace_array, t->num_backtrace_strings);
1336#endif 1330#endif
1337#if DEBUG_FDS 1331#if DEBUG_FDS
1338 if (-1 != rfd) 1332 if (-1 != rfd)
1339 { 1333 {
1340 int flags = fcntl (rfd, F_GETFD); 1334 int flags = fcntl (rfd, F_GETFD);
1341 1335
1342 if ((flags == -1) && (errno == EBADF)) 1336 if ((flags == -1) && (errno == EBADF))
1343 { 1337 {
1344 LOG (GNUNET_ERROR_TYPE_ERROR, 1338 LOG (GNUNET_ERROR_TYPE_ERROR, "Got invalid file descriptor %d!\n", rfd);
1345 "Got invalid file descriptor %d!\n", rfd);
1346#if EXECINFO 1339#if EXECINFO
1347 int i; 1340 int i;
1348 1341
1349 for (i = 0; i < t->num_backtrace_strings; i++) 1342 for (i = 0; i < t->num_backtrace_strings; i++)
1350 LOG (GNUNET_ERROR_TYPE_DEBUG, 1343 LOG (GNUNET_ERROR_TYPE_DEBUG, "Trace: %s\n", t->backtrace_strings[i]);
1351 "Trace: %s\n", t->backtrace_strings[i]);
1352#endif 1344#endif
1353 GNUNET_assert (0); 1345 GNUNET_assert (0);
1354 }
1355 } 1346 }
1347 }
1356 if (-1 != wfd) 1348 if (-1 != wfd)
1357 { 1349 {
1358 int flags = fcntl (wfd, F_GETFD); 1350 int flags = fcntl (wfd, F_GETFD);
1359 1351
1360 if (flags == -1 && errno == EBADF) 1352 if (flags == -1 && errno == EBADF)
1361 { 1353 {
1362 LOG (GNUNET_ERROR_TYPE_ERROR, 1354 LOG (GNUNET_ERROR_TYPE_ERROR, "Got invalid file descriptor %d!\n", wfd);
1363 "Got invalid file descriptor %d!\n", wfd);
1364#if EXECINFO 1355#if EXECINFO
1365 int i; 1356 int i;
1366 1357
1367 for (i = 0; i < t->num_backtrace_strings; i++) 1358 for (i = 0; i < t->num_backtrace_strings; i++)
1368 LOG (GNUNET_ERROR_TYPE_DEBUG, 1359 LOG (GNUNET_ERROR_TYPE_DEBUG, "Trace: %s\n", t->backtrace_strings[i]);
1369 "Trace: %s\n", t->backtrace_strings[i]);
1370#endif 1360#endif
1371 GNUNET_assert (0); 1361 GNUNET_assert (0);
1372 }
1373 } 1362 }
1363 }
1374#endif 1364#endif
1375 t->read_fd = rfd; 1365 t->read_fd = rfd;
1376 GNUNET_assert (wfd >= -1); 1366 GNUNET_assert (wfd >= -1);
@@ -1387,15 +1377,15 @@ add_without_sets (struct GNUNET_TIME_Relative delay, int rfd, int wfd,
1387 pending = t; 1377 pending = t;
1388 max_priority_added = GNUNET_MAX (max_priority_added, t->priority); 1378 max_priority_added = GNUNET_MAX (max_priority_added, t->priority);
1389#if DEBUG_TASKS 1379#if DEBUG_TASKS
1390 LOG (GNUNET_ERROR_TYPE_DEBUG, 1380 LOG (GNUNET_ERROR_TYPE_DEBUG, "Adding task: %llu / %p\n", t->id,
1391 "Adding task: %llu / %p\n", t->id, t->callback_cls); 1381 t->callback_cls);
1392#endif 1382#endif
1393#if EXECINFO 1383#if EXECINFO
1394 int i; 1384 int i;
1395 1385
1396 for (i = 0; i < t->num_backtrace_strings; i++) 1386 for (i = 0; i < t->num_backtrace_strings; i++)
1397 LOG (GNUNET_ERROR_TYPE_DEBUG, 1387 LOG (GNUNET_ERROR_TYPE_DEBUG, "Task %llu trace %d: %s\n", t->id, i,
1398 "Task %llu trace %d: %s\n", t->id, i, t->backtrace_strings[i]); 1388 t->backtrace_strings[i]);
1399#endif 1389#endif
1400 return t->id; 1390 return t->id;
1401} 1391}
@@ -1421,8 +1411,8 @@ add_without_sets (struct GNUNET_TIME_Relative delay, int rfd, int wfd,
1421 */ 1411 */
1422GNUNET_SCHEDULER_TaskIdentifier 1412GNUNET_SCHEDULER_TaskIdentifier
1423GNUNET_SCHEDULER_add_read_net (struct GNUNET_TIME_Relative delay, 1413GNUNET_SCHEDULER_add_read_net (struct GNUNET_TIME_Relative delay,
1424 struct GNUNET_NETWORK_Handle * rfd, 1414 struct GNUNET_NETWORK_Handle *rfd,
1425 GNUNET_SCHEDULER_Task task, void *task_cls) 1415 GNUNET_SCHEDULER_Task task, void *task_cls)
1426{ 1416{
1427#if MINGW 1417#if MINGW
1428 struct GNUNET_NETWORK_FDSet *rs; 1418 struct GNUNET_NETWORK_FDSet *rs;
@@ -1432,14 +1422,14 @@ GNUNET_SCHEDULER_add_read_net (struct GNUNET_TIME_Relative delay,
1432 rs = GNUNET_NETWORK_fdset_create (); 1422 rs = GNUNET_NETWORK_fdset_create ();
1433 GNUNET_NETWORK_fdset_set (rs, rfd); 1423 GNUNET_NETWORK_fdset_set (rs, rfd);
1434 ret = 1424 ret =
1435 GNUNET_SCHEDULER_add_select (check_priority (current_priority), 1425 GNUNET_SCHEDULER_add_select (check_priority (current_priority),
1436 GNUNET_SCHEDULER_NO_TASK, delay, rs, NULL, 1426 GNUNET_SCHEDULER_NO_TASK, delay, rs, NULL,
1437 task, task_cls); 1427 task, task_cls);
1438 GNUNET_NETWORK_fdset_destroy (rs); 1428 GNUNET_NETWORK_fdset_destroy (rs);
1439 return ret; 1429 return ret;
1440#else 1430#else
1441 return add_without_sets (delay, GNUNET_NETWORK_get_fd (rfd), -1, task, 1431 return add_without_sets (delay, GNUNET_NETWORK_get_fd (rfd), -1, task,
1442 task_cls); 1432 task_cls);
1443#endif 1433#endif
1444} 1434}
1445 1435
@@ -1462,8 +1452,8 @@ GNUNET_SCHEDULER_add_read_net (struct GNUNET_TIME_Relative delay,
1462 */ 1452 */
1463GNUNET_SCHEDULER_TaskIdentifier 1453GNUNET_SCHEDULER_TaskIdentifier
1464GNUNET_SCHEDULER_add_write_net (struct GNUNET_TIME_Relative delay, 1454GNUNET_SCHEDULER_add_write_net (struct GNUNET_TIME_Relative delay,
1465 struct GNUNET_NETWORK_Handle * wfd, 1455 struct GNUNET_NETWORK_Handle *wfd,
1466 GNUNET_SCHEDULER_Task task, void *task_cls) 1456 GNUNET_SCHEDULER_Task task, void *task_cls)
1467{ 1457{
1468#if MINGW 1458#if MINGW
1469 struct GNUNET_NETWORK_FDSet *ws; 1459 struct GNUNET_NETWORK_FDSet *ws;
@@ -1473,15 +1463,15 @@ GNUNET_SCHEDULER_add_write_net (struct GNUNET_TIME_Relative delay,
1473 ws = GNUNET_NETWORK_fdset_create (); 1463 ws = GNUNET_NETWORK_fdset_create ();
1474 GNUNET_NETWORK_fdset_set (ws, wfd); 1464 GNUNET_NETWORK_fdset_set (ws, wfd);
1475 ret = 1465 ret =
1476 GNUNET_SCHEDULER_add_select (check_priority (current_priority), 1466 GNUNET_SCHEDULER_add_select (check_priority (current_priority),
1477 GNUNET_SCHEDULER_NO_TASK, delay, NULL, ws, 1467 GNUNET_SCHEDULER_NO_TASK, delay, NULL, ws,
1478 task, task_cls); 1468 task, task_cls);
1479 GNUNET_NETWORK_fdset_destroy (ws); 1469 GNUNET_NETWORK_fdset_destroy (ws);
1480 return ret; 1470 return ret;
1481#else 1471#else
1482 GNUNET_assert (GNUNET_NETWORK_get_fd (wfd) >= 0); 1472 GNUNET_assert (GNUNET_NETWORK_get_fd (wfd) >= 0);
1483 return add_without_sets (delay, -1, GNUNET_NETWORK_get_fd (wfd), task, 1473 return add_without_sets (delay, -1, GNUNET_NETWORK_get_fd (wfd), task,
1484 task_cls); 1474 task_cls);
1485#endif 1475#endif
1486} 1476}
1487 1477
@@ -1504,8 +1494,8 @@ GNUNET_SCHEDULER_add_write_net (struct GNUNET_TIME_Relative delay,
1504 */ 1494 */
1505GNUNET_SCHEDULER_TaskIdentifier 1495GNUNET_SCHEDULER_TaskIdentifier
1506GNUNET_SCHEDULER_add_read_file (struct GNUNET_TIME_Relative delay, 1496GNUNET_SCHEDULER_add_read_file (struct GNUNET_TIME_Relative delay,
1507 const struct GNUNET_DISK_FileHandle * rfd, 1497 const struct GNUNET_DISK_FileHandle *rfd,
1508 GNUNET_SCHEDULER_Task task, void *task_cls) 1498 GNUNET_SCHEDULER_Task task, void *task_cls)
1509{ 1499{
1510#if MINGW 1500#if MINGW
1511 struct GNUNET_NETWORK_FDSet *rs; 1501 struct GNUNET_NETWORK_FDSet *rs;
@@ -1515,9 +1505,9 @@ GNUNET_SCHEDULER_add_read_file (struct GNUNET_TIME_Relative delay,
1515 rs = GNUNET_NETWORK_fdset_create (); 1505 rs = GNUNET_NETWORK_fdset_create ();
1516 GNUNET_NETWORK_fdset_handle_set (rs, rfd); 1506 GNUNET_NETWORK_fdset_handle_set (rs, rfd);
1517 ret = 1507 ret =
1518 GNUNET_SCHEDULER_add_select (check_priority (current_priority), 1508 GNUNET_SCHEDULER_add_select (check_priority (current_priority),
1519 GNUNET_SCHEDULER_NO_TASK, delay, rs, NULL, 1509 GNUNET_SCHEDULER_NO_TASK, delay, rs, NULL,
1520 task, task_cls); 1510 task, task_cls);
1521 GNUNET_NETWORK_fdset_destroy (rs); 1511 GNUNET_NETWORK_fdset_destroy (rs);
1522 return ret; 1512 return ret;
1523#else 1513#else
@@ -1548,8 +1538,8 @@ GNUNET_SCHEDULER_add_read_file (struct GNUNET_TIME_Relative delay,
1548 */ 1538 */
1549GNUNET_SCHEDULER_TaskIdentifier 1539GNUNET_SCHEDULER_TaskIdentifier
1550GNUNET_SCHEDULER_add_write_file (struct GNUNET_TIME_Relative delay, 1540GNUNET_SCHEDULER_add_write_file (struct GNUNET_TIME_Relative delay,
1551 const struct GNUNET_DISK_FileHandle * wfd, 1541 const struct GNUNET_DISK_FileHandle *wfd,
1552 GNUNET_SCHEDULER_Task task, void *task_cls) 1542 GNUNET_SCHEDULER_Task task, void *task_cls)
1553{ 1543{
1554#if MINGW 1544#if MINGW
1555 struct GNUNET_NETWORK_FDSet *ws; 1545 struct GNUNET_NETWORK_FDSet *ws;
@@ -1559,9 +1549,9 @@ GNUNET_SCHEDULER_add_write_file (struct GNUNET_TIME_Relative delay,
1559 ws = GNUNET_NETWORK_fdset_create (); 1549 ws = GNUNET_NETWORK_fdset_create ();
1560 GNUNET_NETWORK_fdset_handle_set (ws, wfd); 1550 GNUNET_NETWORK_fdset_handle_set (ws, wfd);
1561 ret = 1551 ret =
1562 GNUNET_SCHEDULER_add_select (check_priority (current_priority), 1552 GNUNET_SCHEDULER_add_select (check_priority (current_priority),
1563 GNUNET_SCHEDULER_NO_TASK, delay, NULL, ws, 1553 GNUNET_SCHEDULER_NO_TASK, delay, NULL, ws,
1564 task, task_cls); 1554 task, task_cls);
1565 GNUNET_NETWORK_fdset_destroy (ws); 1555 GNUNET_NETWORK_fdset_destroy (ws);
1566 return ret; 1556 return ret;
1567#else 1557#else
@@ -1610,12 +1600,11 @@ GNUNET_SCHEDULER_add_write_file (struct GNUNET_TIME_Relative delay,
1610 */ 1600 */
1611GNUNET_SCHEDULER_TaskIdentifier 1601GNUNET_SCHEDULER_TaskIdentifier
1612GNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio, 1602GNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio,
1613 GNUNET_SCHEDULER_TaskIdentifier 1603 GNUNET_SCHEDULER_TaskIdentifier prerequisite_task,
1614 prerequisite_task, 1604 struct GNUNET_TIME_Relative delay,
1615 struct GNUNET_TIME_Relative delay, 1605 const struct GNUNET_NETWORK_FDSet *rs,
1616 const struct GNUNET_NETWORK_FDSet * rs, 1606 const struct GNUNET_NETWORK_FDSet *ws,
1617 const struct GNUNET_NETWORK_FDSet * ws, 1607 GNUNET_SCHEDULER_Task task, void *task_cls)
1618 GNUNET_SCHEDULER_Task task, void *task_cls)
1619{ 1608{
1620 struct Task *t; 1609 struct Task *t;
1621 1610
@@ -1631,20 +1620,20 @@ GNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio,
1631#if EXECINFO 1620#if EXECINFO
1632 t->num_backtrace_strings = backtrace (backtrace_array, MAX_TRACE_DEPTH); 1621 t->num_backtrace_strings = backtrace (backtrace_array, MAX_TRACE_DEPTH);
1633 t->backtrace_strings = 1622 t->backtrace_strings =
1634 backtrace_symbols (backtrace_array, t->num_backtrace_strings); 1623 backtrace_symbols (backtrace_array, t->num_backtrace_strings);
1635#endif 1624#endif
1636 t->read_fd = -1; 1625 t->read_fd = -1;
1637 t->write_fd = -1; 1626 t->write_fd = -1;
1638 if (rs != NULL) 1627 if (rs != NULL)
1639 { 1628 {
1640 t->read_set = GNUNET_NETWORK_fdset_create (); 1629 t->read_set = GNUNET_NETWORK_fdset_create ();
1641 GNUNET_NETWORK_fdset_copy (t->read_set, rs); 1630 GNUNET_NETWORK_fdset_copy (t->read_set, rs);
1642 } 1631 }
1643 if (ws != NULL) 1632 if (ws != NULL)
1644 { 1633 {
1645 t->write_set = GNUNET_NETWORK_fdset_create (); 1634 t->write_set = GNUNET_NETWORK_fdset_create ();
1646 GNUNET_NETWORK_fdset_copy (t->write_set, ws); 1635 GNUNET_NETWORK_fdset_copy (t->write_set, ws);
1647 } 1636 }
1648 t->id = ++last_id; 1637 t->id = ++last_id;
1649#if PROFILE_DELAYS 1638#if PROFILE_DELAYS
1650 t->start_time = GNUNET_TIME_absolute_get (); 1639 t->start_time = GNUNET_TIME_absolute_get ();
@@ -1652,23 +1641,23 @@ GNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio,
1652 t->prereq_id = prerequisite_task; 1641 t->prereq_id = prerequisite_task;
1653 t->timeout = GNUNET_TIME_relative_to_absolute (delay); 1642 t->timeout = GNUNET_TIME_relative_to_absolute (delay);
1654 t->priority = 1643 t->priority =
1655 check_priority ((prio == 1644 check_priority ((prio ==
1656 GNUNET_SCHEDULER_PRIORITY_KEEP) ? current_priority : 1645 GNUNET_SCHEDULER_PRIORITY_KEEP) ? current_priority :
1657 prio); 1646 prio);
1658 t->lifeness = current_lifeness; 1647 t->lifeness = current_lifeness;
1659 t->next = pending; 1648 t->next = pending;
1660 pending = t; 1649 pending = t;
1661 max_priority_added = GNUNET_MAX (max_priority_added, t->priority); 1650 max_priority_added = GNUNET_MAX (max_priority_added, t->priority);
1662#if DEBUG_TASKS 1651#if DEBUG_TASKS
1663 LOG (GNUNET_ERROR_TYPE_DEBUG, 1652 LOG (GNUNET_ERROR_TYPE_DEBUG, "Adding task: %llu / %p\n", t->id,
1664 "Adding task: %llu / %p\n", t->id, t->callback_cls); 1653 t->callback_cls);
1665#endif 1654#endif
1666#if EXECINFO 1655#if EXECINFO
1667 int i; 1656 int i;
1668 1657
1669 for (i = 0; i < t->num_backtrace_strings; i++) 1658 for (i = 0; i < t->num_backtrace_strings; i++)
1670 LOG (GNUNET_ERROR_TYPE_DEBUG, 1659 LOG (GNUNET_ERROR_TYPE_DEBUG, "Task %llu trace %d: %s\n", t->id, i,
1671 "Task %llu trace %d: %s\n", t->id, i, t->backtrace_strings[i]); 1660 t->backtrace_strings[i]);
1672#endif 1661#endif
1673 return t->id; 1662 return t->id;
1674} 1663}