aboutsummaryrefslogtreecommitdiff
path: root/src/util/scheduler.c
diff options
context:
space:
mode:
authorlurchi <lurchi@strangeplace.net>2018-01-21 13:32:36 +0100
committerlurchi <lurchi@strangeplace.net>2018-01-21 13:32:36 +0100
commit82ab83fc0eb2778b04e4d41e87031ba2d8c3501d (patch)
tree942aaad57bc823b532c99eb1baf69059ee1e01d8 /src/util/scheduler.c
parentf7fc4ee069592858798a94b0b9373d45024ce7b7 (diff)
downloadgnunet-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.c69
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]
330static struct GNUNET_SCHEDULER_Task *ready_tail[GNUNET_SCHEDULER_PRIORITY_COUNT]; 330static 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 */
337static 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 */
343static 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 */
335static unsigned int ready_count; 348static 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
855static void 873static void
856shutdown_cb (void *cls) 874install_parent_control_handler (void *cls)
875{
876 install_parent_control_task = NULL;
877 GNUNET_OS_install_parent_control_handler (NULL);
878}
879
880
881static void
882shutdown_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