diff options
author | lurchi <lurchi@strangeplace.net> | 2018-01-21 13:32:36 +0100 |
---|---|---|
committer | lurchi <lurchi@strangeplace.net> | 2018-01-21 13:32:36 +0100 |
commit | 82ab83fc0eb2778b04e4d41e87031ba2d8c3501d (patch) | |
tree | 942aaad57bc823b532c99eb1baf69059ee1e01d8 /src/util/scheduler.c | |
parent | f7fc4ee069592858798a94b0b9373d45024ce7b7 (diff) | |
download | gnunet-82ab83fc0eb2778b04e4d41e87031ba2d8c3501d.tar.gz gnunet-82ab83fc0eb2778b04e4d41e87031ba2d8c3501d.zip |
check if no tasks are left after the driver loop
- add assertions to make sure all tasks have been run or cancelled
- don't cancel all pending tasks during shutdown, only cancel the two
internal tasks scheduled in GNUNET_SCHEDULER_run_with_driver
Diffstat (limited to 'src/util/scheduler.c')
-rw-r--r-- | src/util/scheduler.c | 69 |
1 files changed, 52 insertions, 17 deletions
diff --git a/src/util/scheduler.c b/src/util/scheduler.c index 1e52dce9f..d0e8f7bc6 100644 --- a/src/util/scheduler.c +++ b/src/util/scheduler.c | |||
@@ -330,6 +330,19 @@ static struct GNUNET_SCHEDULER_Task *ready_head[GNUNET_SCHEDULER_PRIORITY_COUNT] | |||
330 | static struct GNUNET_SCHEDULER_Task *ready_tail[GNUNET_SCHEDULER_PRIORITY_COUNT]; | 330 | static struct GNUNET_SCHEDULER_Task *ready_tail[GNUNET_SCHEDULER_PRIORITY_COUNT]; |
331 | 331 | ||
332 | /** | 332 | /** |
333 | * Task for installing parent control handlers (it might happen that the | ||
334 | * scheduler is shutdown before this task is executed, so | ||
335 | * GNUNET_SCHEDULER_shutdown must cancel it in that case) | ||
336 | */ | ||
337 | static struct GNUNET_SCHEDULER_Task *install_parent_control_task; | ||
338 | |||
339 | /** | ||
340 | * Task for reading from a pipe that signal handlers will use to initiate | ||
341 | * shutdown | ||
342 | */ | ||
343 | static struct GNUNET_SCHEDULER_Task *shutdown_pipe_task; | ||
344 | |||
345 | /** | ||
333 | * Number of tasks on the ready list. | 346 | * Number of tasks on the ready list. |
334 | */ | 347 | */ |
335 | static unsigned int ready_count; | 348 | static unsigned int ready_count; |
@@ -476,6 +489,18 @@ GNUNET_SCHEDULER_shutdown () | |||
476 | { | 489 | { |
477 | struct GNUNET_SCHEDULER_Task *pos; | 490 | struct GNUNET_SCHEDULER_Task *pos; |
478 | 491 | ||
492 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
493 | "GNUNET_SCHEDULER_shutdown\n"); | ||
494 | if (NULL != install_parent_control_task) | ||
495 | { | ||
496 | GNUNET_SCHEDULER_cancel (install_parent_control_task); | ||
497 | install_parent_control_task = NULL; | ||
498 | } | ||
499 | if (NULL != shutdown_pipe_task) | ||
500 | { | ||
501 | GNUNET_SCHEDULER_cancel (shutdown_pipe_task); | ||
502 | shutdown_pipe_task = NULL; | ||
503 | } | ||
479 | while (NULL != (pos = shutdown_head)) | 504 | while (NULL != (pos = shutdown_head)) |
480 | { | 505 | { |
481 | GNUNET_CONTAINER_DLL_remove (shutdown_head, | 506 | GNUNET_CONTAINER_DLL_remove (shutdown_head, |
@@ -627,14 +652,7 @@ shutdown_if_no_lifeness () | |||
627 | for (t = pending_timeout_head; NULL != t; t = t->next) | 652 | for (t = pending_timeout_head; NULL != t; t = t->next) |
628 | if (GNUNET_YES == t->lifeness) | 653 | if (GNUNET_YES == t->lifeness) |
629 | return; | 654 | return; |
630 | /* No lifeness! Cancel all pending tasks the driver knows about and shutdown */ | 655 | /* No lifeness! */ |
631 | t = pending_head; | ||
632 | while (NULL != t) | ||
633 | { | ||
634 | struct GNUNET_SCHEDULER_Task *next = t->next; | ||
635 | GNUNET_SCHEDULER_cancel (t); | ||
636 | t = next; | ||
637 | } | ||
638 | GNUNET_SCHEDULER_shutdown (); | 656 | GNUNET_SCHEDULER_shutdown (); |
639 | } | 657 | } |
640 | 658 | ||
@@ -853,12 +871,20 @@ driver_add_multiple (struct GNUNET_SCHEDULER_Task *t) | |||
853 | 871 | ||
854 | 872 | ||
855 | static void | 873 | static void |
856 | shutdown_cb (void *cls) | 874 | install_parent_control_handler (void *cls) |
875 | { | ||
876 | install_parent_control_task = NULL; | ||
877 | GNUNET_OS_install_parent_control_handler (NULL); | ||
878 | } | ||
879 | |||
880 | |||
881 | static void | ||
882 | shutdown_pipe_cb (void *cls) | ||
857 | { | 883 | { |
858 | char c; | 884 | char c; |
859 | const struct GNUNET_DISK_FileHandle *pr; | 885 | const struct GNUNET_DISK_FileHandle *pr; |
860 | 886 | ||
861 | (void) cls; | 887 | shutdown_pipe_task = NULL; |
862 | pr = GNUNET_DISK_pipe_handle (shutdown_pipe_handle, | 888 | pr = GNUNET_DISK_pipe_handle (shutdown_pipe_handle, |
863 | GNUNET_DISK_PIPE_END_READ); | 889 | GNUNET_DISK_PIPE_END_READ); |
864 | GNUNET_assert (! GNUNET_DISK_handle_invalid (pr)); | 890 | GNUNET_assert (! GNUNET_DISK_handle_invalid (pr)); |
@@ -2007,7 +2033,7 @@ GNUNET_SCHEDULER_run_from_driver (struct GNUNET_SCHEDULER_Handle *sh) | |||
2007 | return GNUNET_NO; | 2033 | return GNUNET_NO; |
2008 | } | 2034 | } |
2009 | scheduler_driver->set_wakeup (scheduler_driver->cls, | 2035 | scheduler_driver->set_wakeup (scheduler_driver->cls, |
2010 | GNUNET_TIME_absolute_get ()); | 2036 | GNUNET_TIME_absolute_get ()); |
2011 | return GNUNET_OK; | 2037 | return GNUNET_OK; |
2012 | } | 2038 | } |
2013 | 2039 | ||
@@ -2087,12 +2113,14 @@ GNUNET_SCHEDULER_run_with_driver (const struct GNUNET_SCHEDULER_Driver *driver, | |||
2087 | 0, | 2113 | 0, |
2088 | sizeof (tsk)); | 2114 | sizeof (tsk)); |
2089 | active_task = &tsk; | 2115 | active_task = &tsk; |
2090 | GNUNET_SCHEDULER_add_now (&GNUNET_OS_install_parent_control_handler, | 2116 | install_parent_control_task = |
2091 | NULL); | 2117 | GNUNET_SCHEDULER_add_now (&install_parent_control_handler, |
2092 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | 2118 | NULL); |
2093 | pr, | 2119 | shutdown_pipe_task = |
2094 | &shutdown_cb, | 2120 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, |
2095 | NULL); | 2121 | pr, |
2122 | &shutdown_pipe_cb, | ||
2123 | NULL); | ||
2096 | current_lifeness = GNUNET_YES; | 2124 | current_lifeness = GNUNET_YES; |
2097 | GNUNET_SCHEDULER_add_with_reason_and_priority (task, | 2125 | GNUNET_SCHEDULER_add_with_reason_and_priority (task, |
2098 | task_cls, | 2126 | task_cls, |
@@ -2107,6 +2135,13 @@ GNUNET_SCHEDULER_run_with_driver (const struct GNUNET_SCHEDULER_Driver *driver, | |||
2107 | GNUNET_NETWORK_fdset_handle_set (sh.rs, pr); | 2135 | GNUNET_NETWORK_fdset_handle_set (sh.rs, pr); |
2108 | ret = driver->loop (driver->cls, | 2136 | ret = driver->loop (driver->cls, |
2109 | &sh); | 2137 | &sh); |
2138 | GNUNET_assert (NULL == pending_head); | ||
2139 | GNUNET_assert (NULL == pending_timeout_head); | ||
2140 | GNUNET_assert (NULL == shutdown_head); | ||
2141 | for (int i = 0; i != GNUNET_SCHEDULER_PRIORITY_COUNT; ++i) | ||
2142 | { | ||
2143 | GNUNET_assert (NULL == ready_head[i]); | ||
2144 | } | ||
2110 | GNUNET_NETWORK_fdset_destroy (sh.rs); | 2145 | GNUNET_NETWORK_fdset_destroy (sh.rs); |
2111 | GNUNET_NETWORK_fdset_destroy (sh.ws); | 2146 | GNUNET_NETWORK_fdset_destroy (sh.ws); |
2112 | 2147 | ||