From f7fc4ee069592858798a94b0b9373d45024ce7b7 Mon Sep 17 00:00:00 2001 From: lurchi Date: Sun, 21 Jan 2018 13:29:20 +0100 Subject: actually test if signals are handled - use a timeout task to prevent the scheduler from shutting down before the signal can be handled - test task cancellation before using the timeout task - use a different status code for each test case --- src/util/test_scheduler.c | 49 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/src/util/test_scheduler.c b/src/util/test_scheduler.c index 55d4c7137..83319d2aa 100644 --- a/src/util/test_scheduler.c +++ b/src/util/test_scheduler.c @@ -29,6 +29,8 @@ static struct GNUNET_DISK_PipeHandle *p; static const struct GNUNET_DISK_FileHandle *fds[2]; +static struct GNUNET_SCHEDULER_Task *never_run_task; + static void task2 (void *cls) @@ -76,7 +78,7 @@ taskNeverRun (void *cls) static void -taskLast (void *cls) +taskLastRd (void *cls) { int *ok = cls; @@ -85,6 +87,27 @@ taskLast (void *cls) } +static void +taskLastSig (void *cls) +{ + int *ok = cls; + + GNUNET_SCHEDULER_cancel (never_run_task); + GNUNET_assert (9 == *ok); + (*ok) = 0; +} + + +static void +taskLastShutdown (void *cls) +{ + int *ok = cls; + + GNUNET_assert (10 == *ok); + (*ok) = 0; +} + + static void taskRd (void *cls) { @@ -97,7 +120,7 @@ taskRd (void *cls) GNUNET_assert (GNUNET_NETWORK_fdset_handle_isset (tc->read_ready, fds[0])); GNUNET_assert (1 == GNUNET_DISK_file_read (fds[0], &c, 1)); (*ok) = 8; - GNUNET_SCHEDULER_add_shutdown (&taskLast, + GNUNET_SCHEDULER_add_shutdown (&taskLastRd, cls); GNUNET_SCHEDULER_shutdown (); } @@ -151,6 +174,8 @@ check () { int ok; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "[Check scheduling]\n"); ok = 1; GNUNET_SCHEDULER_run (&task1, &ok); return ok; @@ -163,8 +188,8 @@ taskShutdown (void *cls) int *ok = cls; GNUNET_assert (1 == *ok); - *ok = 8; - GNUNET_SCHEDULER_add_shutdown (&taskLast, cls); + *ok = 10; + GNUNET_SCHEDULER_add_shutdown (&taskLastShutdown, cls); GNUNET_SCHEDULER_shutdown (); } @@ -178,6 +203,8 @@ checkShutdown () { int ok; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "[Check shutdown]\n"); ok = 1; GNUNET_SCHEDULER_run (&taskShutdown, &ok); return ok; @@ -191,8 +218,12 @@ taskSig (void *cls) int *ok = cls; GNUNET_assert (1 == *ok); - *ok = 8; - GNUNET_SCHEDULER_add_shutdown (&taskLast, cls); + *ok = 9; + GNUNET_SCHEDULER_add_shutdown (&taskLastSig, cls); + never_run_task = + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5), + &taskNeverRun, + NULL); GNUNET_break (0 == PLIBC_KILL (getpid (), GNUNET_TERM_SIG)); } @@ -207,6 +238,8 @@ checkSignal () { int ok; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "[Check signal handling]\n"); ok = 1; GNUNET_SCHEDULER_run (&taskSig, &ok); return ok; @@ -234,6 +267,8 @@ checkCancel () { int ok; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "[Check task cancellation]\n"); ok = 1; GNUNET_SCHEDULER_run (&taskCancel, &ok); return ok; @@ -247,11 +282,11 @@ main (int argc, char *argv[]) GNUNET_log_setup ("test_scheduler", "WARNING", NULL); ret += check (); + ret += checkCancel (); #ifndef MINGW ret += checkSignal (); #endif ret += checkShutdown (); - ret += checkCancel (); GNUNET_DISK_pipe_close (p); return ret; -- cgit v1.2.3 From 82ab83fc0eb2778b04e4d41e87031ba2d8c3501d Mon Sep 17 00:00:00 2001 From: lurchi Date: Sun, 21 Jan 2018 13:32:36 +0100 Subject: 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 --- src/util/scheduler.c | 69 +++++++++++++++++++++++++++++++++++++++------------- 1 file 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 @@ -329,6 +329,19 @@ static struct GNUNET_SCHEDULER_Task *ready_head[GNUNET_SCHEDULER_PRIORITY_COUNT] */ static struct GNUNET_SCHEDULER_Task *ready_tail[GNUNET_SCHEDULER_PRIORITY_COUNT]; +/** + * Task for installing parent control handlers (it might happen that the + * scheduler is shutdown before this task is executed, so + * GNUNET_SCHEDULER_shutdown must cancel it in that case) + */ +static struct GNUNET_SCHEDULER_Task *install_parent_control_task; + +/** + * Task for reading from a pipe that signal handlers will use to initiate + * shutdown + */ +static struct GNUNET_SCHEDULER_Task *shutdown_pipe_task; + /** * Number of tasks on the ready list. */ @@ -476,6 +489,18 @@ GNUNET_SCHEDULER_shutdown () { struct GNUNET_SCHEDULER_Task *pos; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "GNUNET_SCHEDULER_shutdown\n"); + if (NULL != install_parent_control_task) + { + GNUNET_SCHEDULER_cancel (install_parent_control_task); + install_parent_control_task = NULL; + } + if (NULL != shutdown_pipe_task) + { + GNUNET_SCHEDULER_cancel (shutdown_pipe_task); + shutdown_pipe_task = NULL; + } while (NULL != (pos = shutdown_head)) { GNUNET_CONTAINER_DLL_remove (shutdown_head, @@ -627,14 +652,7 @@ shutdown_if_no_lifeness () for (t = pending_timeout_head; NULL != t; t = t->next) if (GNUNET_YES == t->lifeness) return; - /* No lifeness! Cancel all pending tasks the driver knows about and shutdown */ - t = pending_head; - while (NULL != t) - { - struct GNUNET_SCHEDULER_Task *next = t->next; - GNUNET_SCHEDULER_cancel (t); - t = next; - } + /* No lifeness! */ GNUNET_SCHEDULER_shutdown (); } @@ -853,12 +871,20 @@ driver_add_multiple (struct GNUNET_SCHEDULER_Task *t) static void -shutdown_cb (void *cls) +install_parent_control_handler (void *cls) +{ + install_parent_control_task = NULL; + GNUNET_OS_install_parent_control_handler (NULL); +} + + +static void +shutdown_pipe_cb (void *cls) { char c; const struct GNUNET_DISK_FileHandle *pr; - (void) cls; + shutdown_pipe_task = NULL; pr = GNUNET_DISK_pipe_handle (shutdown_pipe_handle, GNUNET_DISK_PIPE_END_READ); GNUNET_assert (! GNUNET_DISK_handle_invalid (pr)); @@ -2007,7 +2033,7 @@ GNUNET_SCHEDULER_run_from_driver (struct GNUNET_SCHEDULER_Handle *sh) return GNUNET_NO; } scheduler_driver->set_wakeup (scheduler_driver->cls, - GNUNET_TIME_absolute_get ()); + GNUNET_TIME_absolute_get ()); return GNUNET_OK; } @@ -2087,12 +2113,14 @@ GNUNET_SCHEDULER_run_with_driver (const struct GNUNET_SCHEDULER_Driver *driver, 0, sizeof (tsk)); active_task = &tsk; - GNUNET_SCHEDULER_add_now (&GNUNET_OS_install_parent_control_handler, - NULL); - GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, - pr, - &shutdown_cb, - NULL); + install_parent_control_task = + GNUNET_SCHEDULER_add_now (&install_parent_control_handler, + NULL); + shutdown_pipe_task = + GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, + pr, + &shutdown_pipe_cb, + NULL); current_lifeness = GNUNET_YES; GNUNET_SCHEDULER_add_with_reason_and_priority (task, task_cls, @@ -2107,6 +2135,13 @@ GNUNET_SCHEDULER_run_with_driver (const struct GNUNET_SCHEDULER_Driver *driver, GNUNET_NETWORK_fdset_handle_set (sh.rs, pr); ret = driver->loop (driver->cls, &sh); + GNUNET_assert (NULL == pending_head); + GNUNET_assert (NULL == pending_timeout_head); + GNUNET_assert (NULL == shutdown_head); + for (int i = 0; i != GNUNET_SCHEDULER_PRIORITY_COUNT; ++i) + { + GNUNET_assert (NULL == ready_head[i]); + } GNUNET_NETWORK_fdset_destroy (sh.rs); GNUNET_NETWORK_fdset_destroy (sh.ws); -- cgit v1.2.3 From 64ccb23dba77c969ef70f3e27272684f6864ac0f Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 21 Jan 2018 15:23:40 +0100 Subject: indentation fixes --- src/fs/gnunet-publish.c | 57 +++++++++++++++++++++---------------------------- src/util/scheduler.c | 12 +++++------ 2 files changed, 30 insertions(+), 39 deletions(-) diff --git a/src/fs/gnunet-publish.c b/src/fs/gnunet-publish.c index 395aad7db..c75469a24 100644 --- a/src/fs/gnunet-publish.c +++ b/src/fs/gnunet-publish.c @@ -895,35 +895,30 @@ main (int argc, char *const *argv) { struct GNUNET_GETOPT_CommandLineOption options[] = { GNUNET_GETOPT_option_uint ('a', - "anonymity", - "LEVEL", - gettext_noop ("set the desired LEVEL of sender-anonymity"), - &bo.anonymity_level), - + "anonymity", + "LEVEL", + gettext_noop ("set the desired LEVEL of sender-anonymity"), + &bo.anonymity_level), GNUNET_GETOPT_option_flag ('d', - "disable-creation-time", - gettext_noop ("disable adding the creation time to the " - "metadata of the uploaded file"), - &do_disable_creation_time), - + "disable-creation-time", + gettext_noop ("disable adding the creation time to the " + "metadata of the uploaded file"), + &do_disable_creation_time), GNUNET_GETOPT_option_flag ('D', - "disable-extractor", - gettext_noop ("do not use libextractor to add keywords or metadata"), - &disable_extractor), - + "disable-extractor", + gettext_noop ("do not use libextractor to add keywords or metadata"), + &disable_extractor), GNUNET_GETOPT_option_flag ('e', - "extract", - gettext_noop ("print list of extracted keywords that would " - "be used, but do not perform upload"), - &extract_only), - + "extract", + gettext_noop ("print list of extracted keywords that would " + "be used, but do not perform upload"), + &extract_only), GNUNET_FS_GETOPT_KEYWORDS ('k', "key", "KEYWORD", gettext_noop ("add an additional keyword for the top-level " "file or directory (this option can be specified multiple times)"), &topKeywords), - GNUNET_FS_GETOPT_METADATA ('m', "meta", "TYPE:VALUE", @@ -955,20 +950,16 @@ main (int argc, char *const *argv) gettext_noop ("publish the files under the pseudonym " "NAME (place file into namespace)"), &pseudonym), - GNUNET_GETOPT_option_uint ('r', - "replication", - "LEVEL", - gettext_noop ("set the desired replication LEVEL"), - &bo.replication_level), - - + "replication", + "LEVEL", + gettext_noop ("set the desired replication LEVEL"), + &bo.replication_level), GNUNET_GETOPT_option_flag ('s', - "simulate-only", - gettext_noop ("only simulate the process but do not do " - "any actual publishing (useful to compute URIs)"), - &do_simulate), - + "simulate-only", + gettext_noop ("only simulate the process but do not do " + "any actual publishing (useful to compute URIs)"), + &do_simulate), GNUNET_GETOPT_option_string ('t', "this", "ID", @@ -981,7 +972,7 @@ main (int argc, char *const *argv) "URI", gettext_noop ("URI to be published (can be used instead of passing a " "file to add keywords to the file with the respective URI)"), - &uri_string), + &uri_string), GNUNET_GETOPT_option_verbose (&verbose), diff --git a/src/util/scheduler.c b/src/util/scheduler.c index d0e8f7bc6..6cf5e1168 100644 --- a/src/util/scheduler.c +++ b/src/util/scheduler.c @@ -679,12 +679,12 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_TaskCallback task, struct DriverContext context = {.scheduled_head = NULL, .scheduled_tail = NULL, .timeout = GNUNET_TIME_UNIT_FOREVER_REL}; - + driver = GNUNET_SCHEDULER_driver_select (); driver->cls = &context; GNUNET_SCHEDULER_run_with_driver (driver, task, task_cls); - + GNUNET_free (driver); } @@ -860,7 +860,7 @@ driver_add_multiple (struct GNUNET_SCHEDULER_Task *t) success = scheduler_driver->add (scheduler_driver->cls, t, fdi) && success; - fdi->et = GNUNET_SCHEDULER_ET_NONE; + fdi->et = GNUNET_SCHEDULER_ET_NONE; } if (GNUNET_YES != success) { @@ -2232,7 +2232,7 @@ select_loop (void *cls, struct DriverContext *context; int select_result; int tasks_ready; - + context = cls; GNUNET_assert (NULL != context); rs = GNUNET_NETWORK_fdset_create (); @@ -2338,7 +2338,7 @@ select_loop (void *cls, } GNUNET_NETWORK_fdset_destroy (rs); GNUNET_NETWORK_fdset_destroy (ws); - return GNUNET_OK; + return GNUNET_OK; } @@ -2348,7 +2348,7 @@ select_set_wakeup (void *cls, { struct DriverContext *context = cls; GNUNET_assert (NULL != context); - + context->timeout = GNUNET_TIME_absolute_get_remaining (dt); } -- cgit v1.2.3