diff options
-rw-r--r-- | src/util/scheduler.c | 47 |
1 files changed, 22 insertions, 25 deletions
diff --git a/src/util/scheduler.c b/src/util/scheduler.c index 03a7c0dfb..7e035ae3d 100644 --- a/src/util/scheduler.c +++ b/src/util/scheduler.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | Copyright (C) 2009-2017 GNUnet e.V. | 3 | Copyright (C) 2009-2017, 2022 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -516,6 +516,8 @@ queue_ready_task (struct GNUNET_SCHEDULER_Task *task) | |||
516 | GNUNET_CONTAINER_DLL_insert_tail (ready_head[p], | 516 | GNUNET_CONTAINER_DLL_insert_tail (ready_head[p], |
517 | ready_tail[p], | 517 | ready_tail[p], |
518 | task); | 518 | task); |
519 | if (p > work_priority) | ||
520 | work_priority = p; | ||
519 | task->in_ready_list = GNUNET_YES; | 521 | task->in_ready_list = GNUNET_YES; |
520 | ready_count++; | 522 | ready_count++; |
521 | } | 523 | } |
@@ -639,29 +641,11 @@ sighandler_pipe () | |||
639 | } | 641 | } |
640 | 642 | ||
641 | 643 | ||
642 | ///** | ||
643 | // * Wait for a short time. | ||
644 | // * Sleeps for @a ms ms (as that should be long enough for virtually all | ||
645 | // * modern systems to context switch and allow another process to do | ||
646 | // * some 'real' work). | ||
647 | // * | ||
648 | // * @param ms how many ms to wait | ||
649 | // */ | ||
650 | // static void | ||
651 | // short_wait (unsigned int ms) | ||
652 | // { | ||
653 | // struct GNUNET_TIME_Relative timeout; | ||
654 | // | ||
655 | // timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, ms); | ||
656 | // (void) GNUNET_NETWORK_socket_select (NULL, NULL, NULL, timeout); | ||
657 | // } | ||
658 | |||
659 | |||
660 | /** | 644 | /** |
661 | * Signal handler called for signals that should cause us to shutdown. | 645 | * Signal handler called for signals that should cause us to shutdown. |
662 | */ | 646 | */ |
663 | static void | 647 | static void |
664 | sighandler_shutdown () | 648 | sighandler_shutdown (void) |
665 | { | 649 | { |
666 | static char c; | 650 | static char c; |
667 | int old_errno = errno; /* backup errno */ | 651 | int old_errno = errno; /* backup errno */ |
@@ -669,15 +653,16 @@ sighandler_shutdown () | |||
669 | if (getpid () != my_pid) | 653 | if (getpid () != my_pid) |
670 | _exit (1); /* we have fork'ed since the signal handler was created, | 654 | _exit (1); /* we have fork'ed since the signal handler was created, |
671 | * ignore the signal, see https://gnunet.org/vfork discussion */ | 655 | * ignore the signal, see https://gnunet.org/vfork discussion */ |
672 | GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle | 656 | GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle ( |
673 | (shutdown_pipe_handle, GNUNET_DISK_PIPE_END_WRITE), | 657 | shutdown_pipe_handle, |
658 | GNUNET_DISK_PIPE_END_WRITE), | ||
674 | &c, sizeof(c)); | 659 | &c, sizeof(c)); |
675 | errno = old_errno; | 660 | errno = old_errno; |
676 | } | 661 | } |
677 | 662 | ||
678 | 663 | ||
679 | static void | 664 | static void |
680 | shutdown_if_no_lifeness () | 665 | shutdown_if_no_lifeness (void) |
681 | { | 666 | { |
682 | struct GNUNET_SCHEDULER_Task *t; | 667 | struct GNUNET_SCHEDULER_Task *t; |
683 | 668 | ||
@@ -2072,6 +2057,8 @@ GNUNET_SCHEDULER_do_work (struct GNUNET_SCHEDULER_Handle *sh) | |||
2072 | } | 2057 | } |
2073 | else | 2058 | else |
2074 | { | 2059 | { |
2060 | struct GNUNET_SCHEDULER_Task *last; | ||
2061 | |||
2075 | /* find out which task priority level we are going to | 2062 | /* find out which task priority level we are going to |
2076 | process this time */ | 2063 | process this time */ |
2077 | max_priority_added = GNUNET_SCHEDULER_PRIORITY_KEEP; | 2064 | max_priority_added = GNUNET_SCHEDULER_PRIORITY_KEEP; |
@@ -2088,7 +2075,9 @@ GNUNET_SCHEDULER_do_work (struct GNUNET_SCHEDULER_Handle *sh) | |||
2088 | } | 2075 | } |
2089 | GNUNET_assert (NULL != pos); /* ready_count wrong? */ | 2076 | GNUNET_assert (NULL != pos); /* ready_count wrong? */ |
2090 | 2077 | ||
2091 | /* process all tasks at this priority level, then yield */ | 2078 | /* process all *existing* tasks at this priority |
2079 | level, then yield */ | ||
2080 | last = ready_tail[work_priority]; | ||
2092 | while (NULL != (pos = ready_head[work_priority])) | 2081 | while (NULL != (pos = ready_head[work_priority])) |
2093 | { | 2082 | { |
2094 | GNUNET_CONTAINER_DLL_remove (ready_head[work_priority], | 2083 | GNUNET_CONTAINER_DLL_remove (ready_head[work_priority], |
@@ -2147,7 +2136,8 @@ GNUNET_SCHEDULER_do_work (struct GNUNET_SCHEDULER_Handle *sh) | |||
2147 | } | 2136 | } |
2148 | if (NULL != pos->fds) | 2137 | if (NULL != pos->fds) |
2149 | { | 2138 | { |
2150 | int del_result = scheduler_driver->del (scheduler_driver->cls, pos); | 2139 | int del_result = scheduler_driver->del (scheduler_driver->cls, |
2140 | pos); | ||
2151 | if (GNUNET_OK != del_result) | 2141 | if (GNUNET_OK != del_result) |
2152 | { | 2142 | { |
2153 | LOG (GNUNET_ERROR_TYPE_ERROR, | 2143 | LOG (GNUNET_ERROR_TYPE_ERROR, |
@@ -2158,6 +2148,13 @@ GNUNET_SCHEDULER_do_work (struct GNUNET_SCHEDULER_Handle *sh) | |||
2158 | active_task = NULL; | 2148 | active_task = NULL; |
2159 | dump_backtrace (pos); | 2149 | dump_backtrace (pos); |
2160 | destroy_task (pos); | 2150 | destroy_task (pos); |
2151 | /* pointer 'pos' was free'd, but we can still safely check for | ||
2152 | pointer equality still. */ | ||
2153 | if (pos == last) | ||
2154 | break; /* All tasks that _were_ ready when we started were | ||
2155 | executed. New tasks may have been added in the | ||
2156 | meantime, but we should check with the OS to | ||
2157 | be sure no higher-priority actions are pending! */ | ||
2161 | } | 2158 | } |
2162 | } | 2159 | } |
2163 | shutdown_if_no_lifeness (); | 2160 | shutdown_if_no_lifeness (); |